Chapter 3. SCSI mid layer

Table of Contents

SCSI midlayer implementation
include/scsi/scsi_device.h
drivers/scsi/scsi.c
drivers/scsi/scsicam.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_ioctl.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib_dma.c
drivers/scsi/scsi_module.c
drivers/scsi/scsi_proc.c
drivers/scsi/scsi_netlink.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysctl.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/hosts.c
drivers/scsi/constants.c
Transport classes
Fibre Channel transport
iSCSI transport class
Serial Attached SCSI (SAS) transport class
SATA transport class
Parallel SCSI (SPI) transport class
SCSI RDMA (SRP) transport class

SCSI midlayer implementation

include/scsi/scsi_device.h

shost_for_each_device — iterate over all devices of a host
__shost_for_each_device — iterate over all devices of a host (UNLOCKED)

drivers/scsi/scsi.c

scsi_device_type — Return 17 char string indicating device type.
__scsi_get_command — Allocate a struct scsi_cmnd
scsi_get_command — Allocate and setup a scsi command block
__scsi_put_command — Free a struct scsi_cmnd
scsi_put_command — Free a scsi command block
scsi_allocate_command — get a fully allocated SCSI command
scsi_free_command — free a command allocated by scsi_allocate_command
scsi_cmd_get_serial — Assign a serial number to a command
scsi_finish_command — cleanup and pass command back to upper layer
scsi_adjust_queue_depth — Let low level drivers change a device's queue depth
scsi_track_queue_full — track QUEUE_FULL events to adjust queue depth
scsi_get_vpd_page — Get Vital Product Data from a SCSI device
scsi_device_get — get an additional reference to a scsi_device
scsi_device_put — release a reference to a scsi_device
starget_for_each_device — helper to walk all devices of a target
__starget_for_each_device — helper to walk all devices of a target (UNLOCKED)
__scsi_device_lookup_by_target — find a device given the target (UNLOCKED)
scsi_device_lookup_by_target — find a device given the target
__scsi_device_lookup — find a device given the host (UNLOCKED)
scsi_device_lookup — find a device given the host

Main file for the SCSI midlayer.

drivers/scsi/scsicam.c

scsi_bios_ptable — Read PC partition table out of first sector of device.
scsicam_bios_param — Determine geometry of a disk in cylinders/heads/sectors.
scsi_partsize — Parse cylinders/heads/sectors from PC partition table

SCSI Common Access Method support functions, for use with HDIO_GETGEO, etc.

drivers/scsi/scsi_error.c

scsi_schedule_eh — schedule EH for SCSI host
scsi_block_when_processing_errors — Prevent cmds from being queued.
scsi_eh_prep_cmnd — Save a scsi command info as part of error recory
scsi_eh_restore_cmnd — Restore a scsi command info as part of error recory
scsi_eh_finish_cmd — Handle a cmd that eh is finished with.
scsi_eh_get_sense — Get device sense data.
scsi_eh_ready_devs — check device ready state and recover if not.
scsi_eh_flush_done_q — finish processed commands or retry them.
scsi_normalize_sense — normalize main elements from either fixed or descriptor sense data format into a common format.
scsi_sense_desc_find — search for a given descriptor type in descriptor sense data format.
scsi_get_sense_info_fld — get information field from sense data (either fixed or descriptor format)
scsi_build_sense_buffer — build sense data in a buffer

Common SCSI error/timeout handling routines.

drivers/scsi/scsi_devinfo.c

scsi_dev_info_list_add — add one dev_info list entry.
scsi_dev_info_list_add_str — parse dev_list and add to the scsi_dev_info_list.
scsi_get_device_flags — get device specific flags from the dynamic device list.
scsi_exit_devinfo — remove /proc/scsi/device_info & the scsi_dev_info_list
scsi_init_devinfo — set up the dynamic device list.

Manage scsi_dev_info_list, which tracks blacklisted and whitelisted devices.

drivers/scsi/scsi_ioctl.c

scsi_ioctl — Dispatch ioctl to scsi device
scsi_nonblockable_ioctl — Handle SG_SCSI_RESET

Handle ioctl() calls for SCSI devices.

drivers/scsi/scsi_lib.c

scsi_execute — insert request and wait for the result
scsi_mode_select — issue a mode select
scsi_mode_sense — issue a mode sense, falling back from 10 to six bytes if necessary.
scsi_test_unit_ready — test if unit is ready
scsi_device_set_state — Take the given device through the device state model.
sdev_evt_send — send asserted event to uevent thread
sdev_evt_alloc — allocate a new scsi event
sdev_evt_send_simple — send asserted event to uevent thread
scsi_device_quiesce — Block user issued commands.
scsi_device_resume — Restart user issued commands to a quiesced device.
scsi_internal_device_block — internal function to put a device temporarily into the SDEV_BLOCK state
scsi_internal_device_unblock — resume a device after a block request
scsi_kmap_atomic_sg — find and atomically map an sg-elemnt
scsi_kunmap_atomic_sg — atomically unmap a virtual address, previously mapped with scsi_kmap_atomic_sg

SCSI queuing library.

drivers/scsi/scsi_lib_dma.c

scsi_dma_map — perform DMA mapping against command's sg lists
scsi_dma_unmap — unmap command's sg lists mapped by scsi_dma_map

SCSI library functions depending on DMA (map and unmap scatter-gather lists).

drivers/scsi/scsi_module.c

The file drivers/scsi/scsi_module.c contains legacy support for old-style host templates. It should never be used by any new driver.

drivers/scsi/scsi_proc.c

proc_scsi_read — handle read from /proc by calling host's proc_info command
proc_scsi_write_proc — Handle write to /proc by calling host's proc_info
scsi_proc_hostdir_add — Create directory in /proc for a scsi host
scsi_proc_hostdir_rm — remove directory in /proc for a scsi host
scsi_proc_host_add — Add entry for this host to appropriate /proc dir
scsi_proc_host_rm — remove this host's entry from /proc
proc_print_scsidevice — return data about this host
scsi_add_single_device — Respond to user request to probe for/add device
scsi_remove_single_device — Respond to user request to remove a device
proc_scsi_write — handle writes to /proc/scsi/scsi
proc_scsi_open — glue function
scsi_init_procfs — create scsi and scsi/scsi in procfs
scsi_exit_procfs — Remove scsi/scsi and scsi from procfs

The functions in this file provide an interface between the PROC file system and the SCSI device drivers It is mainly used for debugging, statistics and to pass information directly to the lowlevel driver. I.E. plumbing to manage /proc/scsi/*

drivers/scsi/scsi_netlink.c

scsi_nl_rcv_msg — Receive message handler.
scsi_nl_rcv_event — Event handler for a netlink socket.
scsi_generic_msg_handler — receive message handler for GENERIC transport messages
scsi_netlink_init — Called by SCSI subsystem to initialize the SCSI transport netlink interface
scsi_netlink_exit — Called by SCSI subsystem to disable the SCSI transport netlink interface

Infrastructure to provide async events from transports to userspace via netlink, using a single NETLINK_SCSITRANSPORT protocol for all transports. See the original patch submission for more details.

drivers/scsi/scsi_scan.c

scsi_unlock_floptical — unlock device via a special MODE SENSE command
scsi_alloc_sdev — allocate and setup a scsi_Device
scsi_alloc_target — allocate a new or find an existing target
scsi_target_reap — check to see if target is in use and destroy if not
sanitize_inquiry_string — remove non-graphical chars from an INQUIRY result string
scsi_probe_lun — probe a single LUN using a SCSI INQUIRY
scsi_add_lun — allocate and fully initialze a scsi_device
scsi_inq_str — print INQUIRY data from min to max index, strip trailing whitespace
scsi_probe_and_add_lun — probe a LUN, if a LUN is found add it
scsi_sequential_lun_scan — sequentially scan a SCSI target
scsi_report_lun_scan — Scan using SCSI REPORT LUN results
scsi_prep_async_scan — prepare for an async scan
scsi_finish_async_scan — asynchronous scan has finished

Scan a host to determine which (if any) devices are attached. The general scanning/probing algorithm is as follows, exceptions are made to it depending on device specific flags, compilation options, and global variable (boot or module load time) settings. A specific LUN is scanned via an INQUIRY command; if the LUN has a device attached, a scsi_device is allocated and setup for it. For every id of every channel on the given host, start by scanning LUN 0. Skip hosts that don't respond at all to a scan of LUN 0. Otherwise, if LUN 0 has a device attached, allocate and setup a scsi_device for it. If target is SCSI-3 or up, issue a REPORT LUN, and scan all of the LUNs returned by the REPORT LUN; else, sequentially scan LUNs up until some maximum is reached, or a LUN is seen that cannot have a device attached to it.

drivers/scsi/scsi_sysctl.c

Set up the sysctl entry: "/dev/scsi/logging_level" (DEV_SCSI_LOGGING_LEVEL) which sets/returns scsi_logging_level.

drivers/scsi/scsi_sysfs.c

scsi_remove_device — unregister a device from the scsi bus
scsi_remove_target — try to remove a target and all its devices

SCSI sysfs interface routines.

drivers/scsi/hosts.c

scsi_host_set_state — Take the given host through the host state model.
scsi_remove_host — remove a scsi host
scsi_add_host_with_dma — add a scsi host with dma device
scsi_host_alloc — register a scsi host adapter instance.
scsi_host_lookup — get a reference to a Scsi_Host by host no
scsi_host_get — inc a Scsi_Host ref count
scsi_host_put — dec a Scsi_Host ref count
scsi_queue_work — Queue work to the Scsi_Host workqueue.
scsi_flush_work — Flush a Scsi_Host's workqueue.

mid to lowlevel SCSI driver interface

drivers/scsi/constants.c

scsi_print_status — print scsi status description

mid to lowlevel SCSI driver interface