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_cmd_get_serial — Assign a serial number to a command
scsi_change_queue_depth — 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_report_opcode — Find out if a given command opcode is supported
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 recovery
scsi_eh_restore_cmnd — Restore a scsi command info as part of error recovery
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_ioctl_reset
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

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

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_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_complete_async_scans — Wait for asynchronous scans to complete
scsi_unlock_floptical — unlock device via a special MODE SENSE command
scsi_alloc_sdev — allocate and setup a scsi_Device
scsi_target_reap_ref_release — remove target from visibility
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

.//drivers/scsi/constants.c — Document generation inconsistency

mid to lowlevel SCSI driver interface