drivers/scsi/3w-xxxx.c
Source file repositories/reference/linux-study-clean/drivers/scsi/3w-xxxx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/3w-xxxx.c- Extension
.c- Size
- 83867 bytes
- Lines
- 2431
- Domain
- Driver Families
- Bucket
- drivers/scsi
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/reboot.hlinux/spinlock.hlinux/interrupt.hlinux/moduleparam.hlinux/errno.hlinux/types.hlinux/delay.hlinux/gfp.hlinux/pci.hlinux/time.hlinux/mutex.hasm/io.hasm/irq.hlinux/uaccess.hscsi/scsi.hscsi/scsi_host.hscsi/scsi_tcq.hscsi/scsi_cmnd.hscsi/scsi_eh.h3w-xxxx.h
Detected Declarations
function tw_check_bitsfunction tw_decode_bitsfunction tw_poll_statusfunction tw_poll_status_gonefunction tw_post_command_packetfunction tw_decode_sensefunction tw_check_errorsfunction tw_empty_response_quefunction tw_state_request_finishfunction tw_state_request_startfunction tw_show_statsfunction tw_aen_read_queuefunction tw_aen_completefunction tw_aen_drain_queuefunction tw_allocate_memoryfunction tw_chrdev_ioctlfunction tw_chrdev_openfunction tw_free_device_extensionfunction tw_initconnectionfunction tw_setfeaturefunction tw_reset_sequencefunction tw_initialize_device_extensionfunction tw_reset_device_extensionfunction tw_scsi_biosparamfunction tw_scsi_eh_resetfunction tw_scsiop_inquiryfunction tw_transfer_internalfunction tw_scsiop_inquiry_completefunction tw_scsiop_mode_sensefunction tw_scsiop_mode_sense_completefunction tw_scsiop_read_capacityfunction tw_scsiop_read_capacity_completefunction tw_scsiop_read_writefunction scsi_for_each_sgfunction tw_scsiop_request_sensefunction tw_scsiop_synchronize_cachefunction tw_scsiop_test_unit_readyfunction tw_scsiop_test_unit_ready_completefunction tw_scsi_queue_lckfunction DEF_SCSI_QCMDfunction __tw_shutdownfunction tw_shutdownfunction tw_sdev_configurefunction tw_probefunction tw_removefunction tw_initfunction tw_exitmodule init tw_init
Annotated Snippet
static const struct file_operations tw_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = tw_chrdev_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.open = tw_chrdev_open,
.release = NULL,
.llseek = noop_llseek,
};
/* This function will free up device extension resources */
static void tw_free_device_extension(TW_Device_Extension *tw_dev)
{
dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
/* Free command packet and generic buffer memory */
if (tw_dev->command_packet_virtual_address[0])
dma_free_coherent(&tw_dev->tw_pci_dev->dev,
sizeof(TW_Command) * TW_Q_LENGTH,
tw_dev->command_packet_virtual_address[0],
tw_dev->command_packet_physical_address[0]);
if (tw_dev->alignment_virtual_address[0])
dma_free_coherent(&tw_dev->tw_pci_dev->dev,
sizeof(TW_Sector) * TW_Q_LENGTH,
tw_dev->alignment_virtual_address[0],
tw_dev->alignment_physical_address[0]);
} /* End tw_free_device_extension() */
/* This function will send an initconnection command to controller */
static int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
{
unsigned long command_que_value;
TW_Command *command_packet;
TW_Response_Queue response_queue;
int request_id = 0;
dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
/* Initialize InitConnection command packet */
if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
return 1;
}
command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
memset(command_packet, 0, sizeof(TW_Sector));
command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_INIT_CONNECTION);
command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
command_packet->request_id = request_id;
command_packet->status = 0x0;
command_packet->flags = 0x0;
command_packet->byte6.message_credits = message_credits;
command_packet->byte8.init_connection.response_queue_pointer = 0x0;
command_que_value = tw_dev->command_packet_physical_address[request_id];
if (command_que_value == 0) {
printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
return 1;
}
/* Send command packet to the board */
outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
/* Poll for completion */
if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
request_id = TW_RESID_OUT(response_queue.response_id);
if (request_id != 0) {
/* unexpected request id */
printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
return 1;
}
if (command_packet->status != 0) {
/* bad response */
tw_decode_sense(tw_dev, request_id, 0);
return 1;
}
}
return 0;
} /* End tw_initconnection() */
/* Set a value in the features table */
static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
unsigned char *val)
{
TW_Param *param;
TW_Command *command_packet;
TW_Response_Queue response_queue;
int request_id = 0;
Annotation
- Immediate include surface: `linux/module.h`, `linux/reboot.h`, `linux/spinlock.h`, `linux/interrupt.h`, `linux/moduleparam.h`, `linux/errno.h`, `linux/types.h`, `linux/delay.h`.
- Detected declarations: `function tw_check_bits`, `function tw_decode_bits`, `function tw_poll_status`, `function tw_poll_status_gone`, `function tw_post_command_packet`, `function tw_decode_sense`, `function tw_check_errors`, `function tw_empty_response_que`, `function tw_state_request_finish`, `function tw_state_request_start`.
- Atlas domain: Driver Families / drivers/scsi.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.