SCSI Interfaces Guide¶
- Author:
James Bottomley
- Author:
Rob Landley
Introduction¶
Protocol vs bus¶
Once upon a time, the Small Computer Systems Interface defined both aparallel I/O bus and a data protocol to connect a wide variety ofperipherals (disk drives, tape drives, modems, printers, scanners,optical drives, test equipment, and medical devices) to a host computer.
Although the old parallel (fast/wide/ultra) SCSI bus has largely fallenout of use, the SCSI command set is more widely used than ever tocommunicate with devices over a number of different buses.
TheSCSI protocol is a big-endianpeer-to-peer packet based protocol. SCSI commands are 6, 10, 12, or 16bytes long, often followed by an associated data payload.
SCSI commands can be transported over just about any kind of bus, andare the default protocol for storage devices attached to USB, SATA, SAS,Fibre Channel, FireWire, and ATAPI devices. SCSI packets are alsocommonly exchanged over Infiniband,TCP/IP (iSCSI), evenParallelports.
Design of the Linux SCSI subsystem¶
The SCSI subsystem uses a three layer design, with upper, mid, and lowlayers. Every operation involving the SCSI subsystem (such as reading asector from a disk) uses one driver at each of the 3 levels: one upperlayer driver, one lower layer driver, and the SCSI midlayer.
The SCSI upper layer provides the interface between userspace and thekernel, in the form of block and char device nodes for I/O and ioctl().The SCSI lower layer contains drivers for specific hardware devices.
In between is the SCSI mid-layer, analogous to a network routing layersuch as the IPv4 stack. The SCSI mid-layer routes a packet based dataprotocol between the upper layer’s /dev nodes and the correspondingdevices in the lower layer. It manages command queues, provides errorhandling and power management functions, and responds to ioctl()requests.
SCSI upper layer¶
The upper layer supports the user-kernel interface by providing devicenodes.
sd (SCSI Disk)¶
sd (sd_mod.o)
sr (SCSI CD-ROM)¶
sr (sr_mod.o)
st (SCSI Tape)¶
st (st.o)
sg (SCSI Generic)¶
sg (sg.o)
ch (SCSI Media Changer)¶
ch (ch.c)
SCSI mid layer¶
SCSI midlayer implementation¶
include/scsi/scsi_device.h¶
- structscsi_vpd¶
SCSI Vital Product Data
Definition:
struct scsi_vpd { struct rcu_head rcu; int len; unsigned char data[];};Members
rcuFor
kfree_rcu().lenLength in bytes ofdata.
dataVPD data as defined in various T10 SCSI standard documents.
- shost_for_each_device¶
shost_for_each_device(sdev,shost)
iterate over all devices of a host
Parameters
sdevthe
structscsi_deviceto use as a cursorshostthe
structscsi_hostto iterate over
Description
Iterator that returns each device attached toshost. This looptakes a reference on each device and releases it at the end. Ifyou break out of the loop, you must call scsi_device_put(sdev).
- __shost_for_each_device¶
__shost_for_each_device(sdev,shost)
iterate over all devices of a host (UNLOCKED)
Parameters
sdevthe
structscsi_deviceto use as a cursorshostthe
structscsi_hostto iterate over
Description
Iterator that returns each device attached toshost. It does _not_take a reference on the scsi_device, so the whole loop must beprotected by shost->host_lock.
Note
The only reason to use this is because you need to access thedevice list in interrupt context. Otherwise you really want to useshost_for_each_device instead.
- boolscsi_device_is_pseudo_dev(structscsi_device*sdev)¶
Whether a device is a pseudo SCSI device.
Parameters
structscsi_device*sdevSCSI device to examine
Description
A pseudo SCSI device can be used to allocate SCSI commands but does not showup in sysfs. Additionally, the logical unit information in*sdev is made up.
This function tests the LUN number instead of comparingsdev withsdev->host->pseudo_sdev because this function may be called beforesdev->host->pseudo_sdev has been initialized.
- intscsi_device_supports_vpd(structscsi_device*sdev)¶
test if a device supports VPD pages
Parameters
structscsi_device*sdevthe
structscsi_deviceto test
Description
If the ‘try_vpd_pages’ flag is set it takes precedence.Otherwise we will assume VPD pages are supported if theSCSI level is at least SPC-3 and ‘skip_vpd_pages’ is not set.
drivers/scsi/scsi.c¶
Main file for the SCSI midlayer.
- intscsi_change_queue_depth(structscsi_device*sdev,intdepth)¶
change a device’s queue depth
Parameters
structscsi_device*sdevSCSI Device in question
intdepthnumber of commands allowed to be queued to the driver
Description
Sets the device queue depth and returns the new value.
- intscsi_track_queue_full(structscsi_device*sdev,intdepth)¶
track QUEUE_FULL events to adjust queue depth
Parameters
structscsi_device*sdevSCSI Device in question
intdepthCurrent number of outstanding SCSI commands on this device,not counting the one returned as QUEUE_FULL.
Description
- This function will track successive QUEUE_FULL events on a
specific SCSI device to determine if and when there is aneed to adjust the queue depth on the device.
Lock Status: None held on entry
Return
0 - No change needed
>0 - Adjust queue depth to this new depth,
-1 - Drop back to untagged operation using host->cmd_per_lun as theuntagged command depth
Notes
- Low level drivers may call this at any time and we will do
“The Right Thing.” We are interrupt context safe.
- intscsi_get_vpd_page(structscsi_device*sdev,u8page,unsignedchar*buf,intbuf_len)¶
Get Vital Product Data from a SCSI device
Parameters
structscsi_device*sdevThe device to ask
u8pageWhich Vital Product Data to return
unsignedchar*bufwhere to store the VPD
intbuf_lennumber of bytes in the VPD buffer area
Description
SCSI devices may optionally supply Vital Product Data. Each ‘page’of VPD is defined in the appropriate SCSI document (eg SPC, SBC).If the device supports this VPD page, this routine fillsbufwith the data from that page and return 0. If the VPD page is notsupported or its content cannot be retrieved, -EINVAL is returned.
- intscsi_report_opcode(structscsi_device*sdev,unsignedchar*buffer,unsignedintlen,unsignedcharopcode,unsignedshortsa)¶
Find out if a given command is supported
Parameters
structscsi_device*sdevscsi device to query
unsignedchar*bufferscratch buffer (must be at least 20 bytes long)
unsignedintlenlength of buffer
unsignedcharopcodeopcode for the command to look up
unsignedshortsaservice action for the command to look up
Description
Uses the REPORT SUPPORTED OPERATION CODES to check support for thecommand identified withopcode andsa. If the command does nothave a service action,sa must be 0. Returns -EINVAL if RSOC fails,0 if the command is not supported and 1 if the device claims tosupport the command.
- intscsi_device_get(structscsi_device*sdev)¶
get an additional reference to a scsi_device
Parameters
structscsi_device*sdevdevice to get a reference to
Description
Gets a reference to the scsi_device and increments the use countof the underlying LLDD module. You must hold host_lock of theparent Scsi_Host or already have a reference when calling this.
This will fail if a device is deleted or cancelled, or when the LLD moduleis in the process of being unloaded.
- voidscsi_device_put(structscsi_device*sdev)¶
release a reference to a scsi_device
Parameters
structscsi_device*sdevdevice to release a reference on.
Description
Release a reference to the scsi_device and decrements the usecount of the underlying LLDD module. The device is freed once the lastuser vanishes.
- voidstarget_for_each_device(structscsi_target*starget,void*data,void(*fn)(structscsi_device*,void*))¶
helper to walk all devices of a target
Parameters
structscsi_target*stargettarget whose devices we want to iterate over.
void*dataOpaque passed to each function call.
void(*fn)(structscsi_device*,void*)Function to call on each device
Description
This traverses over each device ofstarget. The devices havea reference that must be released by scsi_host_put when breakingout of the loop.
- void__starget_for_each_device(structscsi_target*starget,void*data,void(*fn)(structscsi_device*,void*))¶
helper to walk all devices of a target (UNLOCKED)
Parameters
structscsi_target*stargettarget whose devices we want to iterate over.
void*dataparameter for callback
fn()void(*fn)(structscsi_device*,void*)callback function that is invoked for each device
Description
This traverses over each device ofstarget. It does _not_take a reference on the scsi_device, so the whole loop must beprotected by shost->host_lock.
Note
The only reason why drivers would want to use this is becausethey need to access the device list in irq context. Otherwise youreally want to use starget_for_each_device instead.
- structscsi_device*__scsi_device_lookup_by_target(structscsi_target*starget,u64lun)¶
find a device given the target (UNLOCKED)
Parameters
structscsi_target*stargetSCSI target pointer
u64lunSCSI Logical Unit Number
Description
Looks up the scsi_device with the specifiedlun for a givenstarget. The returned scsi_device does not have an additionalreference. You must hold the host’s host_lock over this call andany access to the returned scsi_device. A scsi_device in stateSDEV_DEL is skipped.
Note
The only reason why drivers should use this is becausethey need to access the device list in irq context. Otherwise youreally want to use scsi_device_lookup_by_target instead.
- structscsi_device*scsi_device_lookup_by_target(structscsi_target*starget,u64lun)¶
find a device given the target
Parameters
structscsi_target*stargetSCSI target pointer
u64lunSCSI Logical Unit Number
Description
Looks up the scsi_device with the specifiedlun for a givenstarget. The returned scsi_device has an additional reference thatneeds to be released with scsi_device_put once you’re done with it.
- structscsi_device*__scsi_device_lookup(structScsi_Host*shost,uintchannel,uintid,u64lun)¶
find a device given the host (UNLOCKED)
Parameters
structScsi_Host*shostSCSI host pointer
uintchannelSCSI channel (zero if only one channel)
uintidSCSI target number (physical unit number)
u64lunSCSI Logical Unit Number
Description
Looks up the scsi_device with the specifiedchannel,id,lunfor a given host. The returned scsi_device does not have an additionalreference. You must hold the host’s host_lock over this call and any accessto the returned scsi_device.
Note
The only reason why drivers would want to use this is becausethey need to access the device list in irq context. Otherwise youreally want to use scsi_device_lookup instead.
- structscsi_device*scsi_device_lookup(structScsi_Host*shost,uintchannel,uintid,u64lun)¶
find a device given the host
Parameters
structScsi_Host*shostSCSI host pointer
uintchannelSCSI channel (zero if only one channel)
uintidSCSI target number (physical unit number)
u64lunSCSI Logical Unit Number
Description
Looks up the scsi_device with the specifiedchannel,id,lunfor a given host. The returned scsi_device has an additional reference thatneeds to be released with scsi_device_put once you’re done with it.
drivers/scsi/scsicam.c¶
SCSI Common AccessMethod supportfunctions, for use with HDIO_GETGEO, etc.
- unsignedchar*scsi_bios_ptable(structgendisk*dev)¶
Read PC partition table out of first sector of device.
Parameters
structgendisk*devfrom this device
Description
- Reads the first sector from the device and returns
0x42bytes starting at offset
0x1be.
Return
partition table in kmalloc(GFP_KERNEL) memory, or NULL on error.
- boolscsi_partsize(structgendisk*disk,sector_tcapacity,intgeom[3])¶
Parse cylinders/heads/sectors from PC partition table
Parameters
structgendisk*diskgendisk of the disk to parse
sector_tcapacitysize of the disk in sectors
intgeom[3]output in form of [hds, cylinders, sectors]
Description
Determine the BIOS mapping/geometry used to create the partitiontable, storing the results ingeom.
Return
false on failure,true on success.
- intscsicam_bios_param(structgendisk*disk,sector_tcapacity,int*ip)¶
Determine geometry of a disk in cylinders/heads/sectors.
Parameters
structgendisk*diskwhich device
sector_tcapacitysize of the disk in sectors
int*ipreturn value: ip[0]=heads, ip[1]=sectors, ip[2]=cylinders
Description
- determine the BIOS mapping/geometry used for a drive in a
SCSI-CAM system, storing the results in ip as requiredby the HDIO_GETGEO ioctl().
Return
-1 on failure, 0 on success.
drivers/scsi/scsi_error.c¶
Common SCSI error/timeout handling routines.
- voidscsi_schedule_eh(structScsi_Host*shost)¶
schedule EH for SCSI host
Parameters
structScsi_Host*shostSCSI host to invoke error handling on.
Description
Schedule SCSI EH without scmd.
- intscsi_block_when_processing_errors(structscsi_device*sdev)¶
Prevent cmds from being queued.
Parameters
structscsi_device*sdevDevice on which we are performing recovery.
Description
We block until the host is out of error recovery, and then check tosee whether the host or the device is offline.
- Return value:
0 when dev was taken offline by error recovery. 1 OK to proceed.
- enumscsi_dispositionscsi_check_sense(structscsi_cmnd*scmd)¶
Examine scsi cmd sense
Parameters
structscsi_cmnd*scmdCmd to have sense checked.
Description
- Return value:
SUCCESS or FAILED or NEEDS_RETRY or ADD_TO_MLQUEUE
Notes
When a deferred error is detected the current command hasnot been executed and needs retrying.
- voidscsi_eh_prep_cmnd(structscsi_cmnd*scmd,structscsi_eh_save*ses,unsignedchar*cmnd,intcmnd_size,unsignedsense_bytes)¶
Save a scsi command info as part of error recovery
Parameters
structscsi_cmnd*scmdSCSI command structure to hijack
structscsi_eh_save*sesstructure to save restore information
unsignedchar*cmndCDB to send. Can be NULL if no new cmnd is needed
intcmnd_sizesize in bytes ofcmnd (must be <= MAX_COMMAND_SIZE)
unsignedsense_bytessize of sense data to copy. or 0 (if != 0cmnd is ignored)
Description
This function is used to save a scsi command information before re-executionas part of the error recovery process. Ifsense_bytes is 0 the commandsent must be one that does not transfer any data. Ifsense_bytes != 0cmnd is ignored and this functions sets up a REQUEST_SENSE commandand cmnd buffers to readsense_bytes intoscmd->sense_buffer.
- voidscsi_eh_restore_cmnd(structscsi_cmnd*scmd,structscsi_eh_save*ses)¶
Restore a scsi command info as part of error recovery
Parameters
structscsi_cmnd*scmdSCSI command structure to restore
structscsi_eh_save*sessaved information from a coresponding call to scsi_eh_prep_cmnd
Description
Undo any damage done by abovescsi_eh_prep_cmnd().
- voidscsi_eh_finish_cmd(structscsi_cmnd*scmd,structlist_head*done_q)¶
Handle a cmd that eh is finished with.
Parameters
structscsi_cmnd*scmdOriginal SCSI cmd that eh has finished.
structlist_head*done_qQueue for processed commands.
Notes
We don’t want to use the normal command completion while we are arestill handling errors - it may cause other commands to be queued,and that would disturb what we are doing. Thus we really want tokeep a list of pending commands for final completion, and once weare ready to leave error handling we handle completion for real.
- intscsi_eh_get_sense(structlist_head*work_q,structlist_head*done_q)¶
Get device sense data.
Parameters
structlist_head*work_qQueue of commands to process.
structlist_head*done_qQueue of processed commands.
Description
See if we need to request sense information. if so, then get itnow, so we have a better idea of what to do.
Notes
This has the unfortunate side effect that if a shost adapter doesnot automatically request sense information, we end up shuttingit down before we request it.
All drivers should request sense information internally these days,so for now all I have to say is tough noogies if you end up in here.
- XXX: Long term this code should go away, but that needs an audit of
all LLDDs first.
- voidscsi_eh_ready_devs(structScsi_Host*shost,structlist_head*work_q,structlist_head*done_q)¶
check device ready state and recover if not.
Parameters
structScsi_Host*shosthost to be recovered.
structlist_head*work_qlist_headfor pending commands.structlist_head*done_qlist_headfor processed commands.
- voidscsi_eh_flush_done_q(structlist_head*done_q)¶
finish processed commands or retry them.
Parameters
structlist_head*done_qlist_head of processed commands.
- voidscsi_report_bus_reset(structScsi_Host*shost,intchannel)¶
report bus reset observed
Parameters
structScsi_Host*shostHost in question
intchannelchannel on which reset was observed.
Description
Utility function used by low-level drivers to report thatthey have observed a bus reset on the bus being handled.
Lock status: Host lock must be held.
Return
Nothing
Notes
- This only needs to be called if the reset is one which
originates from an unknown location. Resets originatedby the mid-level itself don’t need to call this, but thereshould be no harm.
The main purpose of this is to make sure that a CHECK_CONDITIONis properly treated.
- voidscsi_report_device_reset(structScsi_Host*shost,intchannel,inttarget)¶
report device reset observed
Parameters
structScsi_Host*shostHost in question
intchannelchannel on which reset was observed
inttargettarget on which reset was observed
Description
Utility function used by low-level drivers to report thatthey have observed a device reset on the device being handled.
Lock status: Host lock must be held
Return
Nothing
Notes
- This only needs to be called if the reset is one which
originates from an unknown location. Resets originatedby the mid-level itself don’t need to call this, but thereshould be no harm.
The main purpose of this is to make sure that a CHECK_CONDITIONis properly treated.
- boolscsi_get_sense_info_fld(constu8*sense_buffer,intsb_len,u64*info_out)¶
get information field from sense data (either fixed or descriptor format)
Parameters
constu8*sense_bufferbyte array of sense data
intsb_lennumber of valid bytes in sense_buffer
u64*info_outpointer to 64 integer where 8 or 4 byte informationfield will be placed if found.
Description
- Return value:
true if information field found, false if not found.
drivers/scsi/scsi_devinfo.c¶
Manage scsi_dev_info_list, which tracks blacklisted and whitelisteddevices.
- intscsi_dev_info_list_add_keyed(intcompatible,char*vendor,char*model,char*strflags,blist_flags_tflags,enumscsi_devinfo_keykey)¶
add one dev_info list entry.
Parameters
intcompatibleif true, null terminate short strings. Otherwise space pad.
char*vendorvendor string
char*modelmodel (product) string
char*strflagsinteger string
blist_flags_tflagsif strflags NULL, use this flag value
enumscsi_devinfo_keykeyspecify list to use
Description
Create and add one dev_info entry forvendor,model,strflags orflag in list specified bykey. Ifcompatible,add to the tail of the list, do not space pad, and setdevinfo->compatible. The scsi_static_device_list entries areadded withcompatible 1 andclfags NULL.
Return
0 OK, -error on failure.
- blist_flags_tscsi_get_device_flags_keyed(structscsi_device*sdev,constunsignedchar*vendor,constunsignedchar*model,enumscsi_devinfo_keykey)¶
get device specific flags from the dynamic device list
Parameters
structscsi_device*sdevscsi_deviceto get flags forconstunsignedchar*vendorvendor name
constunsignedchar*modelmodel name
enumscsi_devinfo_keykeylist to look up
Description
Search the scsi_dev_info_list specified bykey for an entrymatchingvendor andmodel, if found, return the matchingflags value, else return the host or global default settings.Called during scan time.
- intscsi_dev_info_add_list(enumscsi_devinfo_keykey,constchar*name)¶
add a new devinfo list
Parameters
enumscsi_devinfo_keykeykey of the list to add
constchar*nameName of the list to add (for /proc/scsi/device_info)
Description
Adds the requested list, returns zero on success, -EEXIST if thekey is already registered to a list, or other error on failure.
- intscsi_dev_info_remove_list(enumscsi_devinfo_keykey)¶
destroy an added devinfo list
Parameters
enumscsi_devinfo_keykeykey of the list to destroy
Description
Iterates over the entire list first, freeing all the values, thenfrees the list itself. Returns 0 on success or -EINVAL if the keycan’t be found.
drivers/scsi/scsi_ioctl.c¶
Handle ioctl() calls for SCSI devices.
- intscsi_set_medium_removal(structscsi_device*sdev,charstate)¶
send command to allow or prevent medium removal
Parameters
structscsi_device*sdevtarget scsi device
charstateremoval state to set (prevent or allow)
Return
0ifsdev is not removable or not lockable or successful.non-
0is a SCSI result code if > 0 or kernel error code if < 0.Setssdev->locked to the new state on success.
- boolscsi_cmd_allowed(unsignedchar*cmd,boolopen_for_write)¶
Check if the given command is allowed.
Parameters
unsignedchar*cmdSCSI command to check
boolopen_for_writeis the file / block device opened for writing?
Description
Only a subset of commands are allowed for unprivileged users. Commands usedto format the media, update the firmware, etc. are not permitted.
Return
true if the cmd is allowed, otherwisefalse.
- intscsi_ioctl(structscsi_device*sdev,boolopen_for_write,intcmd,void__user*arg)¶
Dispatch ioctl to scsi device
Parameters
structscsi_device*sdevscsi device receiving ioctl
boolopen_for_writeis the file / block device opened for writing?
intcmdwhich ioctl is it
void__user*argdata associated with ioctl
Description
Thescsi_ioctl() function differs from most ioctls in that itdoes not take a major/minor number as the dev field. Rather, it takesa pointer to astructscsi_device.
Return
varies depending on thecmd
- intscsi_ioctl_block_when_processing_errors(structscsi_device*sdev,intcmd,boolndelay)¶
prevent commands from being queued
Parameters
structscsi_device*sdevtarget scsi device
intcmdwhich ioctl is it
boolndelayno delay (non-blocking)
Description
We can process a reset even when a device isn’t fully operable.
Return
0 on success, <0 error code.
drivers/scsi/scsi_lib.c¶
SCSI queuing library.
- voidscsi_failures_reset_retries(structscsi_failures*failures)¶
reset all failures to zero
Parameters
structscsi_failures*failuresstructscsi_failureswith specific failure modes set
- intscsi_execute_cmd(structscsi_device*sdev,constunsignedchar*cmd,blk_opf_topf,void*buffer,unsignedintbufflen,inttimeout,intml_retries,conststructscsi_exec_args*args)¶
insert request and wait for the result
Parameters
structscsi_device*sdevscsi_device
constunsignedchar*cmdscsi command
blk_opf_topfblock layer request cmd_flags
void*bufferdata buffer
unsignedintbufflenlen of buffer
inttimeoutrequest timeout in HZ
intml_retriesnumber of times SCSI midlayer will retry request
conststructscsi_exec_args*argsOptional args. See
structdefinitionfor field descriptions
Description
Returns the scsi_cmnd result field if a command was executed, or a negativeLinux error code if we didn’t get that far.
- blk_status_tscsi_alloc_sgtables(structscsi_cmnd*cmd)¶
Allocate and initialize data and integrity scatterlists
Parameters
structscsi_cmnd*cmdSCSI command data structure to initialize.
Description
Initializescmd->sdb and alsocmd->prot_sdb if data integrity is enabledforcmd.
Return
BLK_STS_OK - on success
BLK_STS_RESOURCE - if the failure is retryable
BLK_STS_IOERR - if the failure is fatal
- structrequest*scsi_alloc_request(structrequest_queue*q,blk_opf_topf,blk_mq_req_flags_tflags)¶
allocate a block request and partially initialize its
scsi_cmnd
Parameters
structrequest_queue*qthe device’s request queue
blk_opf_topfthe request operation code
blk_mq_req_flags_tflagsblock layer allocation flags
Return
structrequest pointer on success orNULL on failure
- structscsi_cmnd*scsi_get_internal_cmd(structscsi_device*sdev,enumdma_data_directiondata_direction,blk_mq_req_flags_tflags)¶
Allocate an internal SCSI command.
Parameters
structscsi_device*sdevSCSI device from which to allocate the command
enumdma_data_directiondata_directionData direction for the allocated command
blk_mq_req_flags_tflagsrequest allocation flags, e.g. BLK_MQ_REQ_RESERVED orBLK_MQ_REQ_NOWAIT.
Description
Allocates a SCSI command for internal LLDD use.
- voidscsi_put_internal_cmd(structscsi_cmnd*scmd)¶
Free an internal SCSI command.
Parameters
structscsi_cmnd*scmdSCSI command to be freed
- structscsi_device*scsi_device_from_queue(structrequest_queue*q)¶
return sdev associated with a request_queue
Parameters
structrequest_queue*qThe request queue to return the sdev from
Description
Return the sdev associated with a request queue or NULL if therequest_queue does not reference a SCSI device.
- voidscsi_block_requests(structScsi_Host*shost)¶
Utility function used by low-level drivers to prevent further commands from being queued to the device.
Parameters
structScsi_Host*shosthost in question
Description
There is no timer nor any other means by which the requests get unblockedother than the low-level driver callingscsi_unblock_requests().
- voidscsi_unblock_requests(structScsi_Host*shost)¶
Utility function used by low-level drivers to allow further commands to be queued to the device.
Parameters
structScsi_Host*shosthost in question
Description
There is no timer nor any other means by which the requests get unblockedother than the low-level driver callingscsi_unblock_requests(). This is doneas an API function so that changes to the internals of the scsi mid-layerwon’t require wholesale changes to drivers that use this feature.
- intscsi_mode_select(structscsi_device*sdev,intpf,intsp,unsignedchar*buffer,intlen,inttimeout,intretries,structscsi_mode_data*data,structscsi_sense_hdr*sshdr)¶
issue a mode select
Parameters
structscsi_device*sdevSCSI device to be queried
intpfPage format bit (1 == standard, 0 == vendor specific)
intspSave page bit (0 == don’t save, 1 == save)
unsignedchar*bufferrequest buffer (may not be smaller than eight bytes)
intlenlength of request buffer.
inttimeoutcommand timeout
intretriesnumber of retries before failing
structscsi_mode_data*datareturns a structure abstracting the mode header data
structscsi_sense_hdr*sshdrplace to put sense data (or NULL if no sense to be collected).must be SCSI_SENSE_BUFFERSIZE big.
Description
Returns zero if successful; negative error number or scsistatus on error
- intscsi_mode_sense(structscsi_device*sdev,intdbd,intmodepage,intsubpage,unsignedchar*buffer,intlen,inttimeout,intretries,structscsi_mode_data*data,structscsi_sense_hdr*sshdr)¶
issue a mode sense, falling back from 10 to six bytes if necessary.
Parameters
structscsi_device*sdevSCSI device to be queried
intdbdset to prevent mode sense from returning block descriptors
intmodepagemode page being requested
intsubpagesub-page of the mode page being requested
unsignedchar*bufferrequest buffer (may not be smaller than eight bytes)
intlenlength of request buffer.
inttimeoutcommand timeout
intretriesnumber of retries before failing
structscsi_mode_data*datareturns a structure abstracting the mode header data
structscsi_sense_hdr*sshdrplace to put sense data (or NULL if no sense to be collected).must be SCSI_SENSE_BUFFERSIZE big.
Description
Returns zero if successful, or a negative error number on failure
- intscsi_test_unit_ready(structscsi_device*sdev,inttimeout,intretries,structscsi_sense_hdr*sshdr)¶
test if unit is ready
Parameters
structscsi_device*sdevscsi device to change the state of.
inttimeoutcommand timeout
intretriesnumber of retries before failing
structscsi_sense_hdr*sshdroutpout pointer for decoded sense information.
Description
Returns zero if successful or an error if TUR failed. Forremovable media, UNIT_ATTENTION sets ->changed flag.
- intscsi_device_set_state(structscsi_device*sdev,enumscsi_device_statestate)¶
Take the given device through the device state model.
Parameters
structscsi_device*sdevscsi device to change the state of.
enumscsi_device_statestatestate to change to.
Description
Returns zero if successful or an error if the requestedtransition is illegal.
- voidsdev_evt_send(structscsi_device*sdev,structscsi_event*evt)¶
send asserted event to uevent thread
Parameters
structscsi_device*sdevscsi_device event occurred on
structscsi_event*evtevent to send
Description
Assert scsi device event asynchronously.
- structscsi_event*sdev_evt_alloc(enumscsi_device_eventevt_type,gfp_tgfpflags)¶
allocate a new scsi event
Parameters
enumscsi_device_eventevt_typetype of event to allocate
gfp_tgfpflagsGFP flags for allocation
Description
Allocates and returns a new scsi_event.
- voidsdev_evt_send_simple(structscsi_device*sdev,enumscsi_device_eventevt_type,gfp_tgfpflags)¶
send asserted event to uevent thread
Parameters
structscsi_device*sdevscsi_device event occurred on
enumscsi_device_eventevt_typetype of event to send
gfp_tgfpflagsGFP flags for allocation
Description
Assert scsi device event asynchronously, given an event type.
- intscsi_device_quiesce(structscsi_device*sdev)¶
Block all commands except power management.
Parameters
structscsi_device*sdevscsi device to quiesce.
Description
This works by trying to transition to the SDEV_QUIESCE state(which must be a legal transition). When the device is in thisstate, only power management requests will be accepted, all others willbe deferred.
Must be called with user context, may sleep.
Returns zero if successful or an error if not.
- voidscsi_device_resume(structscsi_device*sdev)¶
Restart user issued commands to a quiesced device.
Parameters
structscsi_device*sdevscsi device to resume.
Description
Moves the device from quiesced back to running and restarts thequeues.
Must be called with user context, may sleep.
- intscsi_internal_device_block_nowait(structscsi_device*sdev)¶
try to transition to the SDEV_BLOCK state
Parameters
structscsi_device*sdevdevice to block
Description
Pause SCSI command processing on the specified device. Does not sleep.
Returns zero if successful or a negative error code upon failure.
Notes
This routine transitions the device to the SDEV_BLOCK state (which must bea legal transition). When the device is in this state, command processingis paused until the device leaves the SDEV_BLOCK state. See alsoscsi_internal_device_unblock_nowait().
- intscsi_internal_device_unblock_nowait(structscsi_device*sdev,enumscsi_device_statenew_state)¶
resume a device after a block request
Parameters
structscsi_device*sdevdevice to resume
enumscsi_device_statenew_statestate to set the device to after unblocking
Description
Restart the device queue for a previously suspended SCSI device. Does notsleep.
Returns zero if successful or a negative error code upon failure.
Notes
This routine transitions the device to the SDEV_RUNNING state or to one ofthe offline states (which must be a legal transition) allowing the midlayerto goose the queue for this device.
- voidscsi_block_targets(structScsi_Host*shost,structdevice*dev)¶
transition all SCSI child devices to SDEV_BLOCK state
Parameters
structScsi_Host*shostthe Scsi_Host to which this device belongs
structdevice*deva parent device of one or more scsi_target devices
Description
Iterate over all children ofdev, which should be scsi_target devices,and switch all subordinate scsi devices to SDEV_BLOCK state. Wait forongoingscsi_queue_rq() calls to finish. May sleep.
Note
dev must not itself be a scsi_target device.
- intscsi_host_block(structScsi_Host*shost)¶
Try to transition all logical units to the SDEV_BLOCK state
Parameters
structScsi_Host*shostdevice to block
Description
Pause SCSI command processing for all logical units associated with the SCSIhost and wait until pendingscsi_queue_rq() calls have finished.
Returns zero if successful or a negative error code upon failure.
- void*scsi_kmap_atomic_sg(structscatterlist*sgl,intsg_count,size_t*offset,size_t*len)¶
find and atomically map an sg-elemnt
Parameters
structscatterlist*sglscatter-gather list
intsg_countnumber of segments in sg
size_t*offsetoffset in bytes into sg, on return offset into the mapped area
size_t*lenbytes to map, on return number of bytes mapped
Description
Returns virtual address of the start of the mapped page
- voidscsi_kunmap_atomic_sg(void*virt)¶
atomically unmap a virtual address, previously mapped with scsi_kmap_atomic_sg
Parameters
void*virtvirtual address to be unmapped
- intscsi_vpd_lun_id(structscsi_device*sdev,char*id,size_tid_len)¶
return a unique device identification
Parameters
structscsi_device*sdevSCSI device
char*idbuffer for the identification
size_tid_lenlength of the buffer
Description
Copies a unique device identification intoid basedon the information in the VPD page 0x83 of the device.The string will be formatted as a SCSI name string.
Returns the length of the identification or error on failure.If the identifier is longer than the supplied buffer the actualidentifier length is returned and the buffer is not zero-padded.
- intscsi_vpd_tpg_id(structscsi_device*sdev,int*rel_id)¶
return a target port group identifier
Parameters
structscsi_device*sdevSCSI device
int*rel_idpointer to return relative target port in if not
NULL
Description
Returns the Target Port Group identifier from the informationfrom VPD page 0x83 of the device.Optionally setsrel_id to the relative target port on success.
Return
the identifier or error on failure.
- voidscsi_build_sense(structscsi_cmnd*scmd,intdesc,u8key,u8asc,u8ascq)¶
build sense data for a command
Parameters
structscsi_cmnd*scmdscsi command for which the sense should be formatted
intdescSense format (non-zero == descriptor format,0 == fixed format)
u8keySense key
u8ascAdditional sense code
u8ascqAdditional sense code qualifier
drivers/scsi/scsi_lib_dma.c¶
SCSI library functions depending on DMA (map and unmap scatter-gatherlists).
- intscsi_dma_map(structscsi_cmnd*cmd)¶
perform DMA mapping against command’s sg lists
Parameters
structscsi_cmnd*cmdscsi command
Description
Returns the number of sg lists actually used, zero if the sg listsis NULL, or -ENOMEM if the mapping failed.
- voidscsi_dma_unmap(structscsi_cmnd*cmd)¶
unmap command’s sg lists mapped by scsi_dma_map
Parameters
structscsi_cmnd*cmdscsi command
drivers/scsi/scsi_proc.c¶
The functions in this file provide an interface between the PROC filesystem 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/*
- structscsi_proc_entry¶
(host template, SCSI proc dir) association
Definition:
struct scsi_proc_entry { struct list_head entry; const struct scsi_host_template *sht; struct proc_dir_entry *proc_dir; unsigned int present;};Members
entryentry in scsi_proc_list.
shtSCSI host template associated with the procfs directory.
proc_dirprocfs directory associated with the SCSI host template.
presentNumber of SCSI hosts instantiated forsht.
- structproc_dir_entry*scsi_template_proc_dir(conststructscsi_host_template*sht)¶
returns the procfs dir for a SCSI host template
Parameters
conststructscsi_host_template*shtSCSI host template pointer.
- intscsi_proc_hostdir_add(conststructscsi_host_template*sht)¶
Create directory in /proc for a scsi host
Parameters
conststructscsi_host_template*shtowner of this directory
Description
Sets sht->proc_dir to the new directory.
- voidscsi_proc_hostdir_rm(conststructscsi_host_template*sht)¶
remove directory in /proc for a scsi host
Parameters
conststructscsi_host_template*shtowner of directory
- voidscsi_proc_host_add(structScsi_Host*shost)¶
Add entry for this host to appropriate /proc dir
Parameters
structScsi_Host*shosthost to add
- voidscsi_proc_host_rm(structScsi_Host*shost)¶
remove this host’s entry from /proc
Parameters
structScsi_Host*shostwhich host
Parameters
structdevice*devA scsi device
void*datastructseq_fileto output to.
Description
prints Host, Channel, Id, Lun, Vendor, Model, Rev, Type,and revision.
- intscsi_add_single_device(uinthost,uintchannel,uintid,uintlun)¶
Respond to user request to probe for/add device
Parameters
uinthostuser-supplied decimal integer
uintchanneluser-supplied decimal integer
uintiduser-supplied decimal integer
uintlunuser-supplied decimal integer
Description
called by writing “scsi add-single-device” to /proc/scsi/scsi.
doesscsi_host_lookup() and eitheruser_scan() if that transporttype supports it, or elsescsi_scan_host_selected()
Note
this seems to be aimed exclusively at SCSI parallel busses.
- intscsi_remove_single_device(uinthost,uintchannel,uintid,uintlun)¶
Respond to user request to remove a device
Parameters
uinthostuser-supplied decimal integer
uintchanneluser-supplied decimal integer
uintiduser-supplied decimal integer
uintlunuser-supplied decimal integer
Description
called by writing “scsi remove-single-device” to/proc/scsi/scsi. Does ascsi_device_lookup() andscsi_remove_device()
- ssize_tproc_scsi_write(structfile*file,constchar__user*buf,size_tlength,loff_t*ppos)¶
handle writes to /proc/scsi/scsi
Parameters
structfile*filenot used
constchar__user*bufbuffer to write
size_tlengthlength of buf, at most PAGE_SIZE
loff_t*pposnot used
Description
this provides a legacy mechanism to add or remove devices byHost, Channel, ID, and Lun. To use,“echo ‘scsi add-single-device 0 1 2 3’ > /proc/scsi/scsi” or“echo ‘scsi remove-single-device 0 1 2 3’ > /proc/scsi/scsi” with“0 1 2 3” replaced by the Host, Channel, Id, and Lun.
Note
this seems to be aimed at parallel SCSI. Most modern busses (USB,SATA, Firewire, Fibre Channel, etc) dynamically assign these values toprovide a unique identifier and nothing more.
Parameters
structinode*inodenot used
structfile*filepassed to
single_open()
Description
Associates proc_scsi_show with this file
- intscsi_init_procfs(void)¶
create scsi and scsi/scsi in procfs
Parameters
voidno arguments
- voidscsi_exit_procfs(void)¶
Remove scsi/scsi and scsi from procfs
Parameters
voidno arguments
drivers/scsi/scsi_netlink.c¶
Infrastructure to provide async events from transports to userspace vianetlink, using a single NETLINK_SCSITRANSPORT protocol for alltransports. Seethe original patch submissionfor more details.
Parameters
structsk_buff*skbsocket receive buffer
Description
- Extracts message from a receive buffer.
Validates message header and calls appropriate transport message handler
- voidscsi_netlink_init(void)¶
Called by SCSI subsystem to initialize the SCSI transport netlink interface
Parameters
voidno arguments
- voidscsi_netlink_exit(void)¶
Called by SCSI subsystem to disable the SCSI transport netlink interface
Parameters
voidno arguments
drivers/scsi/scsi_scan.c¶
Scan a host to determine which (if any) devices are attached. Thegeneral scanning/probing algorithm is as follows, exceptions are made toit depending on device specific flags, compilation options, and globalvariable (boot or module load time) settings. A specific LUN is scannedvia an INQUIRY command; if the LUN has a device attached, a scsi_deviceis allocated and setup for it. For every id of every channel on thegiven host, start by scanning LUN 0. Skip hosts that don’t respond atall 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 LUNis seen that cannot have a device attached to it.
- voidscsi_sanitize_inquiry_string(unsignedchar*s,intlen)¶
remove non-graphical chars from an INQUIRY result string
Parameters
unsignedchar*sINQUIRY result string to sanitize
intlenlength of the string
Description
The SCSI spec says that INQUIRY vendor, product, and revisionstrings must consist entirely of graphic ASCII characters,padded on the right with spaces. Since not all devices obeythis rule, we will replace non-graphic or non-ASCII characterswith spaces. Exception: a NUL character is interpreted as astring terminator, so all the following characters are set tospaces.
- intscsi_add_device(structScsi_Host*host,uintchannel,uinttarget,u64lun)¶
creates a new SCSI (LU) instance
Parameters
structScsi_Host*hostthe
Scsi_Hostinstance where the device is locateduintchanneltarget channel number (rarely other than
0)uinttargettarget id number
u64lunLUN of target device
Description
Probe for a specific LUN and add it if found.
Notes
This call is usually performed internally during a SCSIbus scan when an HBA is added (i.e.scsi_scan_host()). So itshould only be called if the HBA becomes aware of a new SCSIdevice (LU) afterscsi_scan_host() has completed. If successfulthis call can lead tosdev_init() andsdev_configure() callbacksinto the LLD.
Return
0 on success or negative error code on failure
- voidscsi_scan_target(structdevice*parent,unsignedintchannel,unsignedintid,u64lun,enumscsi_scan_moderescan)¶
scan a target id, possibly including all LUNs on the target.
Parameters
structdevice*parenthost to scan
unsignedintchannelchannel to scan
unsignedintidtarget id to scan
u64lunSpecific LUN to scan or SCAN_WILD_CARD
enumscsi_scan_moderescanpassed to LUN scanning routines; SCSI_SCAN_INITIAL forno rescan, SCSI_SCAN_RESCAN to rescan existing LUNs,and SCSI_SCAN_MANUAL to force scanning even if‘scan=manual’ is set.
Description
Scan the target id onparent,channel, andid. Scan at least LUN 0,and possibly all LUNs on the target id.
First try a REPORT LUN scan, if that does not scan the target, do asequential scan of LUNs on the target id.
- voidscsi_scan_host(structScsi_Host*shost)¶
scan the given adapter
Parameters
structScsi_Host*shostadapter to scan
Notes
Should be called afterscsi_add_host()
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 sysfs interface routines.
- voidscsi_remove_device(structscsi_device*sdev)¶
unregister a device from the scsi bus
Parameters
structscsi_device*sdevscsi_device to unregister
Parameters
structdevice*devgeneric starget or parent of generic stargets to be removed
Note
This is slightly racy. It is possible that if the userrequests the addition of another device then the target won’t beremoved.
drivers/scsi/hosts.c¶
mid to lowlevel SCSI driver interface
- voidscsi_remove_host(structScsi_Host*shost)¶
remove a scsi host
Parameters
structScsi_Host*shosta pointer to a scsi host to remove
- intscsi_add_host_with_dma(structScsi_Host*shost,structdevice*dev,structdevice*dma_dev)¶
add a scsi host with dma device
Parameters
structScsi_Host*shostscsi host pointer to add
structdevice*deva
structdeviceof type scsi classstructdevice*dma_devdma device for the host
Note
You rarely need to worry about this unless you’re in avirtualised host environments, so use the simplerscsi_add_host()function instead.
- Return value:
0 on success / != 0 for error
- structScsi_Host*scsi_host_alloc(conststructscsi_host_template*sht,intprivsize)¶
register a scsi host adapter instance.
Parameters
conststructscsi_host_template*shtpointer to scsi host template
intprivsizeextra bytes to allocate for driver
Note
Allocate a new Scsi_Host and perform basic initialization.The host is not published to the scsi midlayer until scsi_add_hostis called.
- Return value:
Pointer to a new Scsi_Host
- structScsi_Host*scsi_host_lookup(unsignedinthostnum)¶
get a reference to a Scsi_Host by host no
Parameters
unsignedinthostnumhost number to locate
Description
- Return value:
A pointer to located Scsi_Host or NULL.
The caller must do a
scsi_host_put()to drop the referencethatscsi_host_get()took. Theput_device()below droppedthe reference fromclass_find_device().
- structScsi_Host*scsi_host_get(structScsi_Host*shost)¶
inc a Scsi_Host ref count
Parameters
structScsi_Host*shostPointer to Scsi_Host to inc.
- intscsi_host_busy(structScsi_Host*shost)¶
Return the count of in-flight commands
Parameters
structScsi_Host*shostPointer to Scsi_Host
- voidscsi_host_put(structScsi_Host*shost)¶
dec a Scsi_Host ref count
Parameters
structScsi_Host*shostPointer to Scsi_Host to dec.
- intscsi_queue_work(structScsi_Host*shost,structwork_struct*work)¶
Queue work to the Scsi_Host workqueue.
Parameters
structScsi_Host*shostPointer to Scsi_Host.
structwork_struct*workWork to queue for execution.
Description
- Return value:
1 - work queued for execution0 - work is already queued-EINVAL - work queue doesn’t exist
- voidscsi_flush_work(structScsi_Host*shost)¶
Flush a Scsi_Host’s workqueue.
Parameters
structScsi_Host*shostPointer to Scsi_Host.
- voidscsi_host_complete_all_commands(structScsi_Host*shost,enumscsi_host_statusstatus)¶
Terminate all running commands
Parameters
structScsi_Host*shostScsi Host on which commands should be terminated
enumscsi_host_statusstatusStatus to be set for the terminated commands
Description
There is no protection against modification of the numberof outstanding commands. It is the responsibility of thecaller to ensure that concurrent I/O submission and/orcompletion is stopped when calling this function.
- voidscsi_host_busy_iter(structScsi_Host*shost,bool(*fn)(structscsi_cmnd*,void*),void*priv)¶
Iterate over all busy commands
Parameters
structScsi_Host*shostPointer to Scsi_Host.
bool(*fn)(structscsi_cmnd*,void*)Function to call on each busy command
void*privData pointer passed tofn
Description
If locking against concurrent command completions is requiredithas to be provided by the caller
drivers/scsi/scsi_common.c¶
general support functions
- constchar*scsi_device_type(unsignedtype)¶
Return 17-char string indicating device type.
Parameters
unsignedtypetype number to look up
- u64scsilun_to_int(structscsi_lun*scsilun)¶
convert a scsi_lun to an int
Parameters
structscsi_lun*scsilunstructscsi_lunto be converted.
Description
Convertscsilun from a
structscsi_lunto a four-byte host byte-orderedinteger, and return the result. The caller must check fortruncation before using this function.
Notes
For a description of the LUN format, post SCSI-3 see the SCSIArchitecture Model, for SCSI-3 see the SCSI Controller Commands.
Given a
structscsi_lunof: d2 04 0b 03 00 00 00 00, this functionreturns the integer: 0x0b03d204This encoding will return a standard integer LUN for LUNs smallerthan 256, which typically use a single level LUN structure withaddressing method 0.
- voidint_to_scsilun(u64lun,structscsi_lun*scsilun)¶
reverts an int into a scsi_lun
Parameters
u64luninteger to be reverted
structscsi_lun*scsilunstructscsi_lunto be set.
Description
Reverts the functionality of the scsilun_to_int, which packedan 8-byte lun value into an int. This routine unpacks the intback into the lun value.
Notes
Given an integer : 0x0b03d204, this function returns a
structscsi_lunof: d2 04 0b 03 00 00 00 00
- boolscsi_normalize_sense(constu8*sense_buffer,intsb_len,structscsi_sense_hdr*sshdr)¶
normalize main elements from either fixed or descriptor sense data format into a common format.
Parameters
constu8*sense_bufferbyte array containing sense data returned by device
intsb_lennumber of valid bytes in sense_buffer
structscsi_sense_hdr*sshdrpointer to instance of structure that commonelements are written to.
Notes
The “main elements” from sense data are: response_code, sense_key,asc, ascq and additional_length (only for descriptor format).
Typically this function can be called after a device hasresponded to a SCSI command with the CHECK_CONDITION status.
- Return value:
true if valid sense data information found, else false;
- constu8*scsi_sense_desc_find(constu8*sense_buffer,intsb_len,intdesc_type)¶
search for a given descriptor type in descriptor sense data format.
Parameters
constu8*sense_bufferbyte array of descriptor format sense data
intsb_lennumber of valid bytes in sense_buffer
intdesc_typevalue of descriptor type to find(e.g. 0 -> information)
Notes
only valid when sense data is in descriptor format
- Return value:
pointer to start of (first) descriptor if found else NULL
- voidscsi_build_sense_buffer(intdesc,u8*buf,u8key,u8asc,u8ascq)¶
build sense data in a buffer
Parameters
intdescSense format (non-zero == descriptor format,0 == fixed format)
u8*bufWhere to build sense data
u8keySense key
u8ascAdditional sense code
u8ascqAdditional sense code qualifier
- intscsi_set_sense_information(u8*buf,intbuf_len,u64info)¶
set the information field in a formatted sense data buffer
Parameters
u8*bufWhere to build sense data
intbuf_lenbuffer length
u64info64-bit information value to be set
Description
- Return value:
0 on success or -EINVAL for invalid sense buffer length
- intscsi_set_sense_field_pointer(u8*buf,intbuf_len,u16fp,u8bp,boolcd)¶
set the field pointer sense key specific information in a formatted sense data buffer
Parameters
u8*bufWhere to build sense data
intbuf_lenbuffer length
u16fpfield pointer to be set
u8bpbit pointer to be set
boolcdcommand/data bit
Description
- Return value:
0 on success or -EINVAL for invalid sense buffer length
Transport classes¶
Transport classes are service libraries for drivers in the SCSI lowerlayer, which expose transport attributes in sysfs.
Fibre Channel transport¶
The file drivers/scsi/scsi_transport_fc.c defines transport attributesfor Fibre Channel.
- u32fc_get_event_number(void)¶
Obtain the next sequential FC event number
Parameters
voidno arguments
Notes
We could have inlined this, but it would have required fc_event_seq tobe exposed. For now, live with the subroutine call.Atomic used to avoid lock/unlock...
- voidfc_host_post_fc_event(structScsi_Host*shost,u32event_number,enumfc_host_event_codeevent_code,u32data_len,char*data_buf,u64vendor_id)¶
routine to do the work of posting an event on an fc_host.
Parameters
structScsi_Host*shosthost the event occurred on
u32event_numberfc event number obtained from
get_fc_event_number()enumfc_host_event_codeevent_codefc_host event being posted
u32data_lenamount, in bytes, of event data
char*data_bufpointer to event data
u64vendor_idvalue for Vendor id
Notes
This routine assumes no locks are held on entry.
- voidfc_host_post_event(structScsi_Host*shost,u32event_number,enumfc_host_event_codeevent_code,u32event_data)¶
called to post an even on an fc_host.
Parameters
structScsi_Host*shosthost the event occurred on
u32event_numberfc event number obtained from
get_fc_event_number()enumfc_host_event_codeevent_codefc_host event being posted
u32event_data32bits of data for the event being posted
Notes
This routine assumes no locks are held on entry.
- voidfc_host_post_vendor_event(structScsi_Host*shost,u32event_number,u32data_len,char*data_buf,u64vendor_id)¶
called to post a vendor unique event on an fc_host
Parameters
structScsi_Host*shosthost the event occurred on
u32event_numberfc event number obtained from
get_fc_event_number()u32data_lenamount, in bytes, of vendor unique data
char*data_bufpointer to vendor unique data
u64vendor_idVendor id
Notes
This routine assumes no locks are held on entry.
- structfc_rport*fc_find_rport_by_wwpn(structScsi_Host*shost,u64wwpn)¶
find the fc_rport pointer for a given wwpn
Parameters
structScsi_Host*shosthost the fc_rport is associated with
u64wwpnwwpn of the fc_rport device
Notes
This routine assumes no locks are held on entry.
- voidfc_host_fpin_rcv(structScsi_Host*shost,u32fpin_len,char*fpin_buf,u8event_acknowledge)¶
routine to process a received FPIN.
Parameters
structScsi_Host*shosthost the FPIN was received on
u32fpin_lenlength of FPIN payload, in bytes
char*fpin_bufpointer to FPIN payload
u8event_acknowledge1, if LLDD handles this event.
Notes
This routine assumes no locks are held on entry.
- enumscsi_timeout_actionfc_eh_timed_out(structscsi_cmnd*scmd)¶
FC Transport I/O timeout intercept handler
Parameters
structscsi_cmnd*scmdThe SCSI command which timed out
Description
This routine protects against error handlers getting invoked while arport is in a blocked state, typically due to a temporarily loss ofconnectivity. If the error handlers are allowed to proceed, requeststo abort i/o, reset the target, etc will likely fail as there is no wayto communicate with the device to perform the requested function. Thesefailures may result in the midlayer taking the device offline, requiringmanual intervention to restore operation.
This routine, called whenever an i/o times out, validates the state ofthe underlying rport. If the rport is blocked, it returnsEH_RESET_TIMER, which will continue to reschedule the timeout.Eventually, either the device will return, or devloss_tmo will fire,and when the timeout then fires, it will be handled normally.If the rport is not blocked, normal error handling continues.
Notes
This routine assumes no locks are held on entry.
- voidfc_remove_host(structScsi_Host*shost)¶
called to terminate any fc_transport-related elements for a scsi host.
Parameters
structScsi_Host*shostWhich
Scsi_Host
Description
This routine is expected to be called immediately preceding thea driver’s call toscsi_remove_host().
- WARNING: A driver utilizing the fc_transport, which fails to call
this routine prior to
scsi_remove_host(), will leave danglingobjects in /sys/class/fc_remote_ports. Access to any of theseobjects can result in a system crash !!!
Notes
This routine assumes no locks are held on entry.
- structfc_rport*fc_remote_port_add(structScsi_Host*shost,intchannel,structfc_rport_identifiers*ids)¶
notify fc transport of the existence of a remote FC port.
Parameters
structScsi_Host*shostscsi host the remote port is connected to.
intchannelChannel on shost port connected to.
structfc_rport_identifiers*idsThe world wide names, fc address, and FC4 portroles for the remote port.
Description
The LLDD calls this routine to notify the transport of the existenceof a remote port. The LLDD provides the unique identifiers (wwpn,wwn)of the port, it’s FC address (port_id), and the FC4 roles that areactive for the port.
For ports that are FCP targets (aka scsi targets), the FC transportmaintains consistent target id bindings on behalf of the LLDD.A consistent target id binding is an assignment of a target id toa remote port identifier, which persists while the scsi host isattached. The remote port can disappear, then later reappear, andit’s target id assignment remains the same. This allows for shiftsin FC addressing (if binding by wwpn or wwnn) with no apparentchanges to the scsi subsystem which is based on scsi host number andtarget id values. Bindings are only valid during the attachment ofthe scsi host. If the host detaches, then later re-attaches, targetid bindings may change.
This routine is responsible for returning a remote port structure.The routine will search the list of remote ports it maintainsinternally on behalf of consistent target id mappings. If found, theremote port structure will be reused. Otherwise, a new remote portstructure will be allocated.
Whenever a remote port is allocated, a new fc_remote_port classdevice is created.
Should not be called from interrupt context.
Notes
This routine assumes no locks are held on entry.
- voidfc_remote_port_delete(structfc_rport*rport)¶
notifies the fc transport that a remote port is no longer in existence.
Parameters
structfc_rport*rportThe remote port that no longer exists
Description
The LLDD calls this routine to notify the transport that a remoteport is no longer part of the topology. Note: Although a portmay no longer be part of the topology, it may persist in the remoteports displayed by the fc_host. We do this under 2 conditions:
If the port was a scsi target, we delay its deletion by “blocking” it.This allows the port to temporarily disappear, then reappear withoutdisrupting the SCSI device tree attached to it. During the “blocked”period the port will still exist.
If the port was a scsi target and disappears for longer than weexpect, we’ll delete the port and the tear down the SCSI device treeattached to it. However, we want to semi-persist the target id assignedto that port if it eventually does exist. The port structure willremain (although with minimal information) so that the target idbindings also remain.
If the remote port is not an FCP Target, it will be fully torn downand deallocated, including the fc_remote_port class device.
If the remote port is an FCP Target, the port will be placed in atemporary blocked state. From the LLDD’s perspective, the rport nolonger exists. From the SCSI midlayer’s perspective, the SCSI targetexists, but all sdevs on it are blocked from further I/O. The followingis then expected.
If the remote port does not return (signaled by a LLDD call to
fc_remote_port_add()) within the dev_loss_tmo timeout, then thescsi target is removed - killing all outstanding i/o and removing thescsi devices attached to it. The port structure will be marked NotPresent and be partially cleared, leaving only enough information torecognize the remote port relative to the scsi target id binding ifit later appears. The port will remain as long as there is a validbinding (e.g. until the user changes the binding type or unloads thescsi host with the binding).If the remote port returns within the dev_loss_tmo value (and matchesaccording to the target id binding type), the port structure will bereused. If it is no longer a SCSI target, the target will be torndown. If it continues to be a SCSI target, then the target will beunblocked (allowing i/o to be resumed), and a scan will be activatedto ensure that all luns are detected.
Called from normal process context only - cannot be called from interrupt.
Notes
This routine assumes no locks are held on entry.
- voidfc_remote_port_rolechg(structfc_rport*rport,u32roles)¶
notifies the fc transport that the roles on a remote may have changed.
Parameters
structfc_rport*rportThe remote port that changed.
u32rolesNew roles for this port.
Description
The LLDD calls this routine to notify the transport that theroles on a remote port may have changed. The largest effect of this isif a port now becomes a FCP Target, it must be allocated ascsi target id. If the port is no longer a FCP target, anyscsi target id value assigned to it will persist in case therole changes back to include FCP Target. No changes in the scsimidlayer will be invoked if the role changes (in the expectationthat the role will be resumed. If it doesn’t normal error processingwill take place).
Should not be called from interrupt context.
Notes
This routine assumes no locks are held on entry.
- intfc_block_rport(structfc_rport*rport)¶
Block SCSI eh thread for blocked fc_rport.
Parameters
structfc_rport*rportRemote port that scsi_eh is trying to recover.
Description
This routine can be called from a FC LLD scsi_eh callback. Itblocks the scsi_eh thread until the fc_rport leaves theFC_PORTSTATE_BLOCKED, or the fast_io_fail_tmo fires. This isnecessary to avoid the scsi_eh failing recovery actions for blockedrports which would lead to offlined SCSI devices.
Return
0 if the fc_rport left the state FC_PORTSTATE_BLOCKED.FAST_IO_FAIL if the fast_io_fail_tmo fired, this should bepassed back to scsi_eh.
- intfc_block_scsi_eh(structscsi_cmnd*cmnd)¶
Block SCSI eh thread for blocked fc_rport
Parameters
structscsi_cmnd*cmndSCSI command that scsi_eh is trying to recover
Description
This routine can be called from a FC LLD scsi_eh callback. Itblocks the scsi_eh thread until the fc_rport leaves theFC_PORTSTATE_BLOCKED, or the fast_io_fail_tmo fires. This isnecessary to avoid the scsi_eh failing recovery actions for blockedrports which would lead to offlined SCSI devices.
Return
0 if the fc_rport left the state FC_PORTSTATE_BLOCKED.FAST_IO_FAIL if the fast_io_fail_tmo fired, this should bepassed back to scsi_eh.
- structfc_vport*fc_vport_create(structScsi_Host*shost,intchannel,structfc_vport_identifiers*ids)¶
Admin App or LLDD requests creation of a vport
Parameters
structScsi_Host*shostscsi host the virtual port is connected to.
intchannelchannel on shost port connected to.
structfc_vport_identifiers*idsThe world wide names, FC4 port roles, etc forthe virtual port.
Notes
This routine assumes no locks are held on entry.
- intfc_vport_terminate(structfc_vport*vport)¶
Admin App or LLDD requests termination of a vport
Parameters
structfc_vport*vportfc_vport to be terminated
Description
Calls the LLDDvport_delete() function, then deallocates and removesthe vport from the shost and object tree.
Notes
This routine assumes no locks are held on entry.
iSCSI transport class¶
The file drivers/scsi/scsi_transport_iscsi.c defines transportattributes for the iSCSI class, which sends SCSI packets over TCP/IPconnections.
- structiscsi_endpoint*iscsi_lookup_endpoint(u64handle)¶
get ep from handle
Parameters
u64handleendpoint handle
Description
Caller must do a iscsi_put_endpoint.
- structiscsi_bus_flash_session*iscsi_create_flashnode_sess(structScsi_Host*shost,intindex,structiscsi_transport*transport,intdd_size)¶
Add flashnode session entry in sysfs
Parameters
structScsi_Host*shostpointer to host data
intindexindex of flashnode to add in sysfs
structiscsi_transport*transportpointer to transport data
intdd_sizetotal size to allocate
Description
Adds a sysfs entry for the flashnode session attributes
Return
pointer to allocated flashnode sess on successNULL on failure
- structiscsi_bus_flash_conn*iscsi_create_flashnode_conn(structScsi_Host*shost,structiscsi_bus_flash_session*fnode_sess,structiscsi_transport*transport,intdd_size)¶
Add flashnode conn entry in sysfs
Parameters
structScsi_Host*shostpointer to host data
structiscsi_bus_flash_session*fnode_sesspointer to the parent flashnode session entry
structiscsi_transport*transportpointer to transport data
intdd_sizetotal size to allocate
Description
Adds a sysfs entry for the flashnode connection attributes
Return
pointer to allocated flashnode conn on successNULL on failure
- structdevice*iscsi_find_flashnode_sess(structScsi_Host*shost,constvoid*data,device_match_tfn)¶
finds flashnode session entry
Parameters
structScsi_Host*shostpointer to host data
constvoid*datapointer to data containing value to use for comparison
device_match_tfnfunction pointer that does actual comparison
Description
Finds the flashnode session object comparing the data passed using logicdefined in passed function pointer
Return
pointer to found flashnode session device object on successNULL on failure
- structdevice*iscsi_find_flashnode_conn(structiscsi_bus_flash_session*fnode_sess)¶
finds flashnode connection entry
Parameters
structiscsi_bus_flash_session*fnode_sesspointer to parent flashnode session entry
Description
Finds the flashnode connection object comparing the data passed using logicdefined in passed function pointer
Return
pointer to found flashnode connection device object on successNULL on failure
- voidiscsi_destroy_flashnode_sess(structiscsi_bus_flash_session*fnode_sess)¶
destroy flashnode session entry
Parameters
structiscsi_bus_flash_session*fnode_sesspointer to flashnode session entry to be destroyed
Description
Deletes the flashnode session entry and all children flashnode connectionentries from sysfs
- voidiscsi_destroy_all_flashnode(structScsi_Host*shost)¶
destroy all flashnode session entries
Parameters
structScsi_Host*shostpointer to host data
Description
Destroys all the flashnode session entries and all corresponding childrenflashnode connection entries from sysfs
- intiscsi_block_scsi_eh(structscsi_cmnd*cmd)¶
block scsi eh until session state has transistioned
Parameters
structscsi_cmnd*cmdscsi cmd passed to scsi eh handler
Description
If the session is down this function will wait for the recoverytimer to fire or for the session to be logged back in. If therecovery timer fires then FAST_IO_FAIL is returned. The callershould pass this error value to the scsi eh.
- voidiscsi_unblock_session(structiscsi_cls_session*session)¶
set a session as logged in and start IO.
Parameters
structiscsi_cls_session*sessioniscsi session
Description
Mark a session as ready to accept IO.
- voidiscsi_force_destroy_session(structiscsi_cls_session*session)¶
destroy a session from the kernel
Parameters
structiscsi_cls_session*sessionsession to destroy
Description
Force the destruction of a session from the kernel. This should only beused when userspace is no longer running during system shutdown.
- structiscsi_cls_conn*iscsi_alloc_conn(structiscsi_cls_session*session,intdd_size,uint32_tcid)¶
alloc iscsi class connection
Parameters
structiscsi_cls_session*sessioniscsi cls session
intdd_sizeprivate driver data size
uint32_tcidconnection id
- intiscsi_add_conn(structiscsi_cls_conn*conn)¶
add iscsi class connection
Parameters
structiscsi_cls_conn*conniscsi cls connection
Description
This will expose iscsi_cls_conn to sysfs so make sure the relatedresources for sysfs attributes are initialized before calling this.
- voidiscsi_remove_conn(structiscsi_cls_conn*conn)¶
remove iscsi class connection from sysfs
Parameters
structiscsi_cls_conn*conniscsi cls connection
Description
Remove iscsi_cls_conn from sysfs, and wait for previousread/write of iscsi_cls_conn’s attributes in sysfs to finish.
- intiscsi_session_event(structiscsi_cls_session*session,enumiscsi_uevent_eevent)¶
send session destr. completion event
Parameters
structiscsi_cls_session*sessioniscsi class session
enumiscsi_uevent_eeventtype of event
Serial Attached SCSI (SAS) transport class¶
The file drivers/scsi/scsi_transport_sas.c defines transportattributes for Serial Attached SCSI, a variant of SATA aimed at largehigh-end systems.
The SAS transport class contains common code to deal with SAS HBAs, anapproximated representation of SAS topologies in the driver model, andvarious sysfs attributes to expose these topologies and managementinterfaces to userspace.
In addition to the basic SCSI core objects this transport classintroduces two additional intermediate objects: The SAS PHY asrepresented bystructsas_phy defines an “outgoing” PHY on a SAS HBA orExpander, and the SAS remote PHY represented bystructsas_rphy definesan “incoming” PHY on a SAS Expander or end device. Note that this ispurely a software concept, the underlying hardware for a PHY and aremote PHY is the exactly the same.
There is no concept of a SAS port in this code, users can see what PHYsform a wide port based on the port_identifier attribute, which is thesame for all PHYs in a port.
Parameters
structdevice*devdevice belonging to the sas object
Description
Removes all SAS PHYs and remote PHYs for a given object
- voidsas_remove_host(structScsi_Host*shost)¶
tear down a Scsi_Host’s SAS data structures
Parameters
structScsi_Host*shostScsi Host that is torn down
Description
Removes all SAS PHYs and remote PHYs for a given Scsi_Host and remove theScsi_Host as well.
Note
Do not callscsi_remove_host() on the Scsi_Host any more, as it isalready removed.
- u64sas_get_address(structscsi_device*sdev)¶
return the SAS address of the device
Parameters
structscsi_device*sdevscsi device
Description
Returns the SAS address of the scsi device
- unsignedintsas_tlr_supported(structscsi_device*sdev)¶
checking TLR bit in vpd 0x90
Parameters
structscsi_device*sdevscsi device struct
Description
Check Transport Layer Retries are supported or not.If vpd page 0x90 is present, TRL is supported.
- voidsas_disable_tlr(structscsi_device*sdev)¶
setting TLR flags
Parameters
structscsi_device*sdevscsi device struct
Description
Seting tlr_enabled flag to 0.
- voidsas_enable_tlr(structscsi_device*sdev)¶
setting TLR flags
Parameters
structscsi_device*sdevscsi device struct
Description
Seting tlr_enabled flag 1.
- boolsas_ata_ncq_prio_supported(structscsi_device*sdev)¶
Check for ATA NCQ command priority support
Parameters
structscsi_device*sdevSCSI device
Description
Check if an ATA device supports NCQ priority using VPD page 89h (ATAInformation). Since this VPD page is implemented only for ATA devices,this function always returns false for SCSI devices.
- structsas_phy*sas_phy_alloc(structdevice*parent,intnumber)¶
allocates and initialize a SAS PHY structure
Parameters
structdevice*parentParent device
intnumberPhy index
Description
Allocates an SAS PHY structure. It will be added in the device treebelow the device specified byparent, which has to be either a Scsi_Hostor sas_rphy.
Return
SAS PHY allocated orNULL if the allocation failed.
- intsas_phy_add(structsas_phy*phy)¶
add a SAS PHY to the device hierarchy
Parameters
structsas_phy*phyThe PHY to be added
Description
Publishes a SAS PHY to the rest of the system.
- voidsas_phy_free(structsas_phy*phy)¶
free a SAS PHY
Parameters
structsas_phy*phySAS PHY to free
Description
Frees the specified SAS PHY.
Note
This function must only be called on a PHY that has notsuccessfully been added using
sas_phy_add().
- voidsas_phy_delete(structsas_phy*phy)¶
remove SAS PHY
Parameters
structsas_phy*phySAS PHY to remove
Description
Removes the specified SAS PHY. If the SAS PHY has anassociated remote PHY it is removed before.
- intscsi_is_sas_phy(conststructdevice*dev)¶
check if a
structdevicerepresents a SAS PHY
Parameters
conststructdevice*devdevice to check
Return
1 if the device represents a SAS PHY,0 else
- structsas_port*sas_port_alloc(structdevice*parent,intport_id)¶
allocate and initialize a SAS port structure
Parameters
structdevice*parentparent device
intport_idport number
Description
Allocates a SAS port structure. It will be added to the device treebelow the device specified byparent which must be either a Scsi_Hostor a sas_expander_device.
Return
NULL on error
Parameters
structdevice*parentparent device
Description
Allocates a SAS port structure and a number to go with it. Thisinterface is really for adapters where the port number has nomeansing, so the sas class should manage them. It will be added tothe device tree below the device specified byparent which must beeither a Scsi_Host or a sas_expander_device.
Return
NULL on error
- intsas_port_add(structsas_port*port)¶
add a SAS port to the device hierarchy
Parameters
structsas_port*portport to be added
Description
publishes a port to the rest of the system
- voidsas_port_free(structsas_port*port)¶
free a SAS PORT
Parameters
structsas_port*portSAS PORT to free
Description
Frees the specified SAS PORT.
Note
This function must only be called on a PORT that has notsuccessfully been added using
sas_port_add().
- voidsas_port_delete(structsas_port*port)¶
remove SAS PORT
Parameters
structsas_port*portSAS PORT to remove
Description
Removes the specified SAS PORT. If the SAS PORT has anassociated phys, unlink them from the port as well.
- intscsi_is_sas_port(conststructdevice*dev)¶
check if a
structdevicerepresents a SAS port
Parameters
conststructdevice*devdevice to check
Return
1 if the device represents a SAS Port,0 else
- structsas_phy*sas_port_get_phy(structsas_port*port)¶
try to take a reference on a port member
Parameters
structsas_port*portport to check
- voidsas_port_add_phy(structsas_port*port,structsas_phy*phy)¶
add another phy to a port to form a wide port
Parameters
structsas_port*portport to add the phy to
structsas_phy*phyphy to add
Description
When a port is initially created, it is empty (has no phys). Allports must have at least one phy to operated, and all wide portsmust have at least two. The current code makes no differencebetween ports and wide ports, but the only object that can beconnected to a remote device is a port, so ports must be formed onall devices with phys if they’re connected to anything.
- voidsas_port_delete_phy(structsas_port*port,structsas_phy*phy)¶
remove a phy from a port or wide port
Parameters
structsas_port*portport to remove the phy from
structsas_phy*phyphy to remove
Description
This operation is used for tearing down ports again. It must bedone to every port or wide port before calling sas_port_delete.
- structsas_rphy*sas_end_device_alloc(structsas_port*parent)¶
allocate an rphy for an end device
Parameters
structsas_port*parentwhich port
Description
Allocates an SAS remote PHY structure, connected toparent.
Return
SAS PHY allocated orNULL if the allocation failed.
- structsas_rphy*sas_expander_alloc(structsas_port*parent,enumsas_device_typetype)¶
allocate an rphy for an end device
Parameters
structsas_port*parentwhich port
enumsas_device_typetypeSAS_EDGE_EXPANDER_DEVICE or SAS_FANOUT_EXPANDER_DEVICE
Description
Allocates an SAS remote PHY structure, connected toparent.
Return
SAS PHY allocated orNULL if the allocation failed.
- intsas_rphy_add(structsas_rphy*rphy)¶
add a SAS remote PHY to the device hierarchy
Parameters
structsas_rphy*rphyThe remote PHY to be added
Description
Publishes a SAS remote PHY to the rest of the system.
- voidsas_rphy_free(structsas_rphy*rphy)¶
free a SAS remote PHY
Parameters
structsas_rphy*rphySAS remote PHY to free
Description
Frees the specified SAS remote PHY.
Note
This function must only be called on a remotePHY that has not successfully been added using
sas_rphy_add()(or has beensas_rphy_remove()’d)
- voidsas_rphy_delete(structsas_rphy*rphy)¶
remove and free SAS remote PHY
Parameters
structsas_rphy*rphySAS remote PHY to remove and free
Description
Removes the specified SAS remote PHY and frees it.
- voidsas_rphy_unlink(structsas_rphy*rphy)¶
unlink SAS remote PHY
Parameters
structsas_rphy*rphySAS remote phy to unlink from its parent port
Description
Removes port reference to an rphy
- voidsas_rphy_remove(structsas_rphy*rphy)¶
remove SAS remote PHY
Parameters
structsas_rphy*rphySAS remote phy to remove
Description
Removes the specified SAS remote PHY.
- intscsi_is_sas_rphy(conststructdevice*dev)¶
check if a
structdevicerepresents a SAS remote PHY
Parameters
conststructdevice*devdevice to check
Return
1 if the device represents a SAS remote PHY,0 else
- structscsi_transport_template*sas_attach_transport(structsas_function_template*ft)¶
instantiate SAS transport template
Parameters
structsas_function_template*ftSAS transport class function template
- voidsas_release_transport(structscsi_transport_template*t)¶
release SAS transport template instance
Parameters
structscsi_transport_template*ttransport template instance
SATA transport class¶
The SATA transport is handled by libata, which has its own book ofdocumentation in this directory.
Parallel SCSI (SPI) transport class¶
The file drivers/scsi/scsi_transport_spi.c defines transportattributes for traditional (fast/wide/ultra) SCSI buses.
- voidspi_dv_device(structscsi_device*sdev)¶
Do Domain Validation on the device
Parameters
structscsi_device*sdevscsi device to validate
Description
Performs the domain validation on the given device in thecurrent execution thread. Since DV operations may sleep,the current thread must have user context. Also no SCSIrelated locks that would deadlock I/O issued by the DV maybe held.
- voidspi_schedule_dv_device(structscsi_device*sdev)¶
schedule domain validation to occur on the device
Parameters
structscsi_device*sdevThe device to validate
Description
Identical to
spi_dv_device()above, except that the DV will bescheduled to occur in a workqueue later. All memory allocationsare atomic, so may be called from any context including those holdingSCSI locks.
- voidspi_display_xfer_agreement(structscsi_target*starget)¶
Print the current target transfer agreement
Parameters
structscsi_target*stargetThe target for which to display the agreement
Description
Each SPI port is required to maintain a transfer agreement for eachother port on the bus. This function prints a one-line summary ofthe current agreement; more detailed information is available in sysfs.
- intspi_populate_tag_msg(unsignedchar*msg,structscsi_cmnd*cmd)¶
place a tag message in a buffer
Parameters
unsignedchar*msgpointer to the area to place the tag
structscsi_cmnd*cmdpointer to the scsi command for the tag
Notes
designed to create the correct type of tag message for theparticular request. Returns the size of the tag message.May return 0 if TCQ is disabled for this device.
SCSI RDMA (SRP) transport class¶
The file drivers/scsi/scsi_transport_srp.c defines transportattributes for SCSI over Remote Direct Memory Access.
- intsrp_tmo_valid(intreconnect_delay,intfast_io_fail_tmo,longdev_loss_tmo)¶
check timeout combination validity
Parameters
intreconnect_delayReconnect delay in seconds.
intfast_io_fail_tmoFast I/O fail timeout in seconds.
longdev_loss_tmoDevice loss timeout in seconds.
Description
The combination of the timeout parameters must be such that SCSI commandsare finished in a reasonable time. Hence do not allow the fast I/O failtimeout to exceed SCSI_DEVICE_BLOCK_MAX_TIMEOUT nor allow dev_loss_tmo toexceed that limit if failing I/O fast has been disabled. Furthermore, theseparameters must be such that multipath can detect failed paths timely.Hence do not allow all three parameters to be disabled simultaneously.
- voidsrp_start_tl_fail_timers(structsrp_rport*rport)¶
start the transport layer failure timers
Parameters
structsrp_rport*rportSRP target port.
Description
Start the transport layer fast I/O failure and device loss timers. Do notmodify a timer that was already started.
- intsrp_reconnect_rport(structsrp_rport*rport)¶
reconnect to an SRP target port
Parameters
structsrp_rport*rportSRP target port.
Description
Blocks SCSI command queueing before invokingreconnect() such thatqueuecommand() won’t be invoked concurrently withreconnect() from outsidethe SCSI EH. This is important since areconnect() implementation mayreallocate resources needed byqueuecommand().
Notes
This function neither waits until outstanding requests have finished nortries to abort these. It is the responsibility of the
reconnect()function to finish outstanding commands before reconnecting to the targetport.It is the responsibility of the caller to ensure that the resourcesreallocated by the
reconnect()function won’t be used while this functionis in progress. One possible strategy is to invoke this function fromthe context of the SCSI EH thread only. Another possible strategy is tolock the rport mutex inside each SCSI LLD callback that can be invoked bythe SCSI EH (the scsi_host_template.eh_*() functions and also thescsi_host_template.queuecommand()function).
- enumscsi_timeout_actionsrp_timed_out(structscsi_cmnd*scmd)¶
SRP transport intercept of the SCSI timeout EH
Parameters
structscsi_cmnd*scmdSCSI command.
Description
If a timeout occurs while an rport is in the blocked state, ask the SCSIEH to continue waiting (SCSI_EH_RESET_TIMER). Otherwise let the SCSI corehandle the timeout (SCSI_EH_NOT_HANDLED).
Note
This function is called from soft-IRQ context and with the requestqueue lock held.
- voidsrp_rport_get(structsrp_rport*rport)¶
increment rport reference count
Parameters
structsrp_rport*rportSRP target port.
- voidsrp_rport_put(structsrp_rport*rport)¶
decrement rport reference count
Parameters
structsrp_rport*rportSRP target port.
- structsrp_rport*srp_rport_add(structScsi_Host*shost,structsrp_rport_identifiers*ids)¶
add a SRP remote port to the device hierarchy
Parameters
structScsi_Host*shostscsi host the remote port is connected to.
structsrp_rport_identifiers*idsThe port id for the remote port.
Description
Publishes a port to the rest of the system.
- voidsrp_rport_del(structsrp_rport*rport)¶
remove a SRP remote port
Parameters
structsrp_rport*rportSRP remote port to remove
Description
Removes the specified SRP remote port.
- voidsrp_remove_host(structScsi_Host*shost)¶
tear down a Scsi_Host’s SRP data structures
Parameters
structScsi_Host*shostScsi Host that is torn down
Description
Removes all SRP remote ports for a given Scsi_Host.Must be called just before scsi_remove_host for SRP HBAs.
- voidsrp_stop_rport_timers(structsrp_rport*rport)¶
stop the transport layer recovery timers
Parameters
structsrp_rport*rportSRP remote port for which to stop the timers.
Description
Must be called aftersrp_remove_host() andscsi_remove_host(). The callermust hold a reference on the rport (rport->dev) and on the SCSI host(rport->dev.parent).
- structscsi_transport_template*srp_attach_transport(structsrp_function_template*ft)¶
instantiate SRP transport template
Parameters
structsrp_function_template*ftSRP transport class function template
- voidsrp_release_transport(structscsi_transport_template*t)¶
release SRP transport template instance
Parameters
structscsi_transport_template*ttransport template instance
SCSI lower layer¶
Host Bus Adapter transport types¶
Many modern device controllers use the SCSI command set as a protocol tocommunicate with their devices through many different types of physicalconnections.
In SCSI language a bus capable of carrying SCSI commands is called a“transport”, and a controller connecting to such a bus is called a “hostbus adapter” (HBA).
Debug transport¶
The file drivers/scsi/scsi_debug.c simulates a host adapter with avariable number of disks (or disk like devices) attached, sharing acommon amount of RAM. Does a lot of checking to make sure that we arenot getting blocks mixed up, and panics the kernel if anything out ofthe ordinary is seen.
To be more realistic, the simulated devices have the transportattributes of SAS disks.
For documentation seehttp://sg.danny.cz/sg/scsi_debug.html
todo¶
Parallel (fast/wide/ultra) SCSI, USB, SATA, SAS, Fibre Channel,FireWire, ATAPI devices, Infiniband, Parallel ports,netlink...