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 busses.
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,I2O, 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¶
- struct
scsi_vpd¶ SCSI Vital Product Data
Definition
struct scsi_vpd { struct rcu_head rcu; int len; unsigned char data[];};Members
rcu- For
kfree_rcu(). len- Length in bytes ofdata.
data- VPD data as defined in various T10 SCSI standard documents.
shost_for_each_device(sdev,shost)¶iterate over all devices of a host
Parameters
sdev- the
structscsi_deviceto use as a cursor shost- the
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(sdev,shost)¶iterate over all devices of a host (UNLOCKED)
Parameters
sdev- the
structscsi_deviceto use as a cursor shost- the
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.
- int
scsi_device_supports_vpd(struct scsi_device * sdev)¶ test if a device supports VPD pages
Parameters
structscsi_device*sdev- the
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.
- int
scsi_change_queue_depth(struct scsi_device * sdev, int depth)¶ change a device’s queue depth
Parameters
structscsi_device*sdev- SCSI Device in question
intdepth- number of commands allowed to be queued to the driver
Description
Sets the device queue depth and returns the new value.
- int
scsi_track_queue_full(struct scsi_device * sdev, int depth)¶ track QUEUE_FULL events to adjust queue depth
Parameters
structscsi_device*sdev- SCSI Device in question
intdepth- Current 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 the untagged command depth
Notes
- Low level drivers may call this at any time and we will do
- “The Right Thing.” We are interrupt context safe.
- int
scsi_get_vpd_page(struct scsi_device * sdev, u8 page, unsigned char * buf, int buf_len)¶ Get Vital Product Data from a SCSI device
Parameters
structscsi_device*sdev- The device to ask
u8page- Which Vital Product Data to return
unsignedchar*buf- where to store the VPD
intbuf_len- number 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 returns a pointerto a buffer containing the data from that page. The caller isresponsible for callingkfree() on this pointer when it is no longerneeded. If we cannot retrieve the VPD page this routine returnsNULL.
- int
scsi_report_opcode(struct scsi_device * sdev, unsigned char * buffer, unsigned int len, unsigned char opcode)¶ Find out if a given command opcode is supported
Parameters
structscsi_device*sdev- scsi device to query
unsignedchar*buffer- scratch buffer (must be at least 20 bytes long)
unsignedintlen- length of buffer
unsignedcharopcode- opcode for command to look up
Description
Uses the REPORT SUPPORTED OPERATION CODES to look up the givenopcode. Returns -EINVAL if RSOC fails, 0 if the command opcode isunsupported and 1 if the device claims to support the command.
- int
scsi_device_get(struct scsi_device * sdev)¶ get an additional reference to a scsi_device
Parameters
structscsi_device*sdev- device 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.
- void
scsi_device_put(struct scsi_device * sdev)¶ release a reference to a scsi_device
Parameters
structscsi_device*sdev- device 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.
- void
starget_for_each_device(struct scsi_target * starget, void * data, void (*fn)(struct scsi_device *, void *))¶ helper to walk all devices of a target
Parameters
structscsi_target*starget- target whose devices we want to iterate over.
void*data- Opaque passed to each function call.
void(*)(structscsi_device*,void*)fn- 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(struct scsi_target * starget, void * data, void (*fn)(struct scsi_device *, void *))¶ helper to walk all devices of a target (UNLOCKED)
Parameters
structscsi_target*starget- target whose devices we want to iterate over.
void*data- parameter for callbackfn()
void(*)(structscsi_device*,void*)fn- 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.
- struct scsi_device *
__scsi_device_lookup_by_target(struct scsi_target * starget, u64 lun)¶ find a device given the target (UNLOCKED)
Parameters
structscsi_target*starget- SCSI target pointer
u64lun- SCSI 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.
- struct scsi_device *
scsi_device_lookup_by_target(struct scsi_target * starget, u64 lun)¶ find a device given the target
Parameters
structscsi_target*starget- SCSI target pointer
u64lun- SCSI 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.
- struct scsi_device *
__scsi_device_lookup(struct Scsi_Host * shost, uint channel, uint id, u64 lun)¶ find a device given the host (UNLOCKED)
Parameters
structScsi_Host*shost- SCSI host pointer
uintchannel- SCSI channel (zero if only one channel)
uintid- SCSI target number (physical unit number)
u64lun- SCSI 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.
- struct scsi_device *
scsi_device_lookup(struct Scsi_Host * shost, uint channel, uint id, u64 lun)¶ find a device given the host
Parameters
structScsi_Host*shost- SCSI host pointer
uintchannel- SCSI channel (zero if only one channel)
uintid- SCSI target number (physical unit number)
u64lun- SCSI 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.
- unsigned char *
scsi_bios_ptable(struct block_device * dev)¶ Read PC partition table out of first sector of device.
Parameters
structblock_device*dev- from 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.
- bool
scsi_partsize(struct block_device * bdev, sector_t capacity, int geom)¶ Parse cylinders/heads/sectors from PC partition table
Parameters
structblock_device*bdev- block device to parse
sector_tcapacity- size of the disk in sectors
intgeom- 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.
- int
scsicam_bios_param(struct block_device * bdev, sector_t capacity, int * ip)¶ Determine geometry of a disk in cylinders/heads/sectors.
Parameters
structblock_device*bdev- which device
sector_tcapacity- size of the disk in sectors
int*ip- return 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.
- void
scsi_schedule_eh(struct Scsi_Host * shost)¶ schedule EH for SCSI host
Parameters
structScsi_Host*shost- SCSI host to invoke error handling on.
Description
Schedule SCSI EH without scmd.
- int
scsi_block_when_processing_errors(struct scsi_device * sdev)¶ Prevent cmds from being queued.
Parameters
structscsi_device*sdev- Device 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.
- int
scsi_check_sense(struct scsi_cmnd * scmd)¶ Examine scsi cmd sense
Parameters
structscsi_cmnd*scmd- Cmd 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.
- void
scsi_eh_prep_cmnd(struct scsi_cmnd * scmd, struct scsi_eh_save * ses, unsigned char * cmnd, int cmnd_size, unsigned sense_bytes)¶ Save a scsi command info as part of error recovery
Parameters
structscsi_cmnd*scmd- SCSI command structure to hijack
structscsi_eh_save*ses- structure to save restore information
unsignedchar*cmnd- CDB to send. Can be NULL if no new cmnd is needed
intcmnd_size- size in bytes ofcmnd (must be <= BLK_MAX_CDB)
unsignedsense_bytes- size 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.
- void
scsi_eh_restore_cmnd(struct scsi_cmnd * scmd, struct scsi_eh_save * ses)¶ Restore a scsi command info as part of error recovery
Parameters
structscsi_cmnd*scmd- SCSI command structure to restore
structscsi_eh_save*ses- saved information from a coresponding call to scsi_eh_prep_cmnd
Description
Undo any damage done by abovescsi_eh_prep_cmnd().
- void
scsi_eh_finish_cmd(struct scsi_cmnd * scmd, struct list_head * done_q)¶ Handle a cmd that eh is finished with.
Parameters
structscsi_cmnd*scmd- Original SCSI cmd that eh has finished.
structlist_head*done_q- Queue 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.
- int
scsi_eh_get_sense(struct list_head * work_q, struct list_head * done_q)¶ Get device sense data.
Parameters
structlist_head*work_q- Queue of commands to process.
structlist_head*done_q- Queue 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.
- void
scsi_eh_ready_devs(struct Scsi_Host * shost, struct list_head * work_q, struct list_head * done_q)¶ check device ready state and recover if not.
Parameters
structScsi_Host*shost- host to be recovered.
structlist_head*work_qlist_headfor pending commands.structlist_head*done_qlist_headfor processed commands.
- void
scsi_eh_flush_done_q(struct list_head * done_q)¶ finish processed commands or retry them.
Parameters
structlist_head*done_q- list_head of processed commands.
- bool
scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, u64 * info_out)¶ get information field from sense data (either fixed or descriptor format)
Parameters
constu8*sense_buffer- byte array of sense data
intsb_len- number of valid bytes in sense_buffer
u64*info_out- pointer 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.
- int
scsi_dev_info_list_add(int compatible, char * vendor, char * model, char * strflags, blist_flags_t flags)¶ add one dev_info list entry.
Parameters
intcompatible- if true, null terminate short strings. Otherwise space pad.
char*vendor- vendor string
char*model- model (product) string
char*strflags- integer string
blist_flags_tflags- if strflags NULL, use this flag value
Description
Create and add one dev_info entry forvendor,model,strflags orflag. Ifcompatible, add to the tail of the list, do not spacepad, and set devinfo->compatible. The scsi_static_device_list entriesare added withcompatible 1 andclfags NULL.
Return
0 OK, -error on failure.
- struct scsi_dev_info_list *
scsi_dev_info_list_find(const char * vendor, const char * model, enum scsi_devinfo_key key)¶ find a matching dev_info list entry.
Parameters
constchar*vendor- full vendor string
constchar*model- full model (product) string
enumscsi_devinfo_keykey- specify list to use
Description
Finds the first dev_info entry matchingvendor,modelin list specified bykey.
Return
pointer to matching entry, or ERR_PTR on failure.
- int
scsi_dev_info_list_add_str(char * dev_list)¶ parse dev_list and add to the scsi_dev_info_list.
Parameters
char*dev_list- string of device flags to add
Description
Parse dev_list, and add entries to the scsi_dev_info_list.dev_list is of the form “vendor:product:flag,vendor:product:flag”.dev_list is modified via strsep. Can be called for command lineaddition, for proc or mabye a sysfs interface.
Return
0 if OK, -error on failure.
- blist_flags_t
scsi_get_device_flags(struct scsi_device * sdev, const unsigned char * vendor, const unsigned char * model)¶ get device specific flags from the dynamic device list.
Parameters
structscsi_device*sdevscsi_deviceto get flags forconstunsignedchar*vendor- vendor name
constunsignedchar*model- model name
Description
Search the global scsi_dev_info_list (specified by list zero)for an entry matchingvendor andmodel, if found, return thematching flags value, else return the host or global defaultsettings. Called during scan time.
- void
scsi_exit_devinfo(void)¶ remove /proc/scsi/device_info & the scsi_dev_info_list
Parameters
void- no arguments
- int
scsi_init_devinfo(void)¶ set up the dynamic device list.
Parameters
void- no arguments
Description
Add command line entries from scsi_dev_flags, then addscsi_static_device_list entries to the scsi device info list.
drivers/scsi/scsi_ioctl.c¶
Handle ioctl() calls for SCSI devices.
- int
scsi_ioctl(struct scsi_device * sdev, int cmd, void __user * arg)¶ Dispatch ioctl to scsi device
Parameters
structscsi_device*sdev- scsi device receiving ioctl
intcmd- which ioctl is it
void__user*arg- data 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.
drivers/scsi/scsi_lib.c¶
SCSI queuing library.
- int
__scsi_execute(struct scsi_device * sdev, const unsigned char * cmd, int data_direction, void * buffer, unsigned bufflen, unsigned char * sense, struct scsi_sense_hdr * sshdr, int timeout, int retries, u64 flags, req_flags_t rq_flags, int * resid)¶ insert request and wait for the result
Parameters
structscsi_device*sdev- scsi device
constunsignedchar*cmd- scsi command
intdata_direction- data direction
void*buffer- data buffer
unsignedbufflen- len of buffer
unsignedchar*sense- optional sense buffer
structscsi_sense_hdr*sshdr- optional decoded sense header
inttimeout- request timeout in seconds
intretries- number of times to retry request
u64flags- flags for ->cmd_flags
req_flags_trq_flags- flags for ->rq_flags
int*resid- optional residual length
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_t
scsi_init_io(struct scsi_cmnd * cmd)¶ SCSI I/O initialization function.
Parameters
structscsi_cmnd*cmd- command descriptor we wish to initialize
Return
- BLK_STS_OK - on success
- BLK_STS_RESOURCE - if the failure is retryable
- BLK_STS_IOERR - if the failure is fatal
- struct scsi_device *
scsi_device_from_queue(struct request_queue * q)¶ return sdev associated with a request_queue
Parameters
structrequest_queue*q- The 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.
- void
scsi_block_requests(struct Scsi_Host * shost)¶ Utility function used by low-level drivers to prevent further commands from being queued to the device.
Parameters
structScsi_Host*shost- host 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().
- void
scsi_unblock_requests(struct Scsi_Host * shost)¶ Utility function used by low-level drivers to allow further commands to be queued to the device.
Parameters
structScsi_Host*shost- host 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.
- int
scsi_mode_select(struct scsi_device * sdev, int pf, int sp, int modepage, unsigned char * buffer, int len, int timeout, int retries, struct scsi_mode_data * data, struct scsi_sense_hdr * sshdr)¶ issue a mode select
Parameters
structscsi_device*sdev- SCSI device to be queried
intpf- Page format bit (1 == standard, 0 == vendor specific)
intsp- Save page bit (0 == don’t save, 1 == save)
intmodepage- mode page being requested
unsignedchar*buffer- request buffer (may not be smaller than eight bytes)
intlen- length of request buffer.
inttimeout- command timeout
intretries- number of retries before failing
structscsi_mode_data*data- returns 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.
Returns zero if successful; negative error number or scsistatus on error
- int
scsi_mode_sense(struct scsi_device * sdev, int dbd, int modepage, unsigned char * buffer, int len, int timeout, int retries, struct scsi_mode_data * data, struct scsi_sense_hdr * sshdr)¶ issue a mode sense, falling back from 10 to six bytes if necessary.
Parameters
structscsi_device*sdev- SCSI device to be queried
intdbd- set if mode sense will allow block descriptors to be returned
intmodepage- mode page being requested
unsignedchar*buffer- request buffer (may not be smaller than eight bytes)
intlen- length of request buffer.
inttimeout- command timeout
intretries- number of retries before failing
structscsi_mode_data*data- returns 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.
Returns zero if unsuccessful, or the header offset (either 4or 8 depending on whether a six or ten byte command wasissued) if successful.
- int
scsi_test_unit_ready(struct scsi_device * sdev, int timeout, int retries, struct scsi_sense_hdr * sshdr)¶ test if unit is ready
Parameters
structscsi_device*sdev- scsi device to change the state of.
inttimeout- command timeout
intretries- number of retries before failing
structscsi_sense_hdr*sshdroutpout pointer for decoded sense information.
Returns zero if unsuccessful or an error if TUR failed. Forremovable media, UNIT_ATTENTION sets ->changed flag.
- int
scsi_device_set_state(struct scsi_device * sdev, enum scsi_device_state state)¶ Take the given device through the device state model.
Parameters
structscsi_device*sdev- scsi device to change the state of.
enumscsi_device_statestatestate to change to.
Returns zero if successful or an error if the requestedtransition is illegal.
- void
sdev_evt_send(struct scsi_device * sdev, struct scsi_event * evt)¶ send asserted event to uevent thread
Parameters
structscsi_device*sdev- scsi_device event occurred on
structscsi_event*evtevent to send
Assert scsi device event asynchronously.
- struct scsi_event *
sdev_evt_alloc(enum scsi_device_event evt_type, gfp_t gfpflags)¶ allocate a new scsi event
Parameters
enumscsi_device_eventevt_type- type of event to allocate
gfp_tgfpflagsGFP flags for allocation
Allocates and returns a new scsi_event.
- void
sdev_evt_send_simple(struct scsi_device * sdev, enum scsi_device_event evt_type, gfp_t gfpflags)¶ send asserted event to uevent thread
Parameters
structscsi_device*sdev- scsi_device event occurred on
enumscsi_device_eventevt_type- type of event to send
gfp_tgfpflagsGFP flags for allocation
Assert scsi device event asynchronously, given an event type.
- int
scsi_device_quiesce(struct scsi_device * sdev)¶ Block user issued commands.
Parameters
structscsi_device*sdevscsi device to quiesce.
This works by trying to transition to the SDEV_QUIESCE state(which must be a legal transition). When the device is in thisstate, only special requests will be accepted, all others willbe deferred. Since special requests may also be requeued requests,a successful return doesn’t guarantee the device will betotally quiescent.
Must be called with user context, may sleep.
Returns zero if unsuccessful or an error if not.
- void
scsi_device_resume(struct scsi_device * sdev)¶ Restart user issued commands to a quiesced device.
Parameters
structscsi_device*sdevscsi device to resume.
Moves the device from quiesced back to running and restarts thequeues.
Must be called with user context, may sleep.
- int
scsi_internal_device_block_nowait(struct scsi_device * sdev)¶ try to transition to the SDEV_BLOCK state
Parameters
structscsi_device*sdev- device 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().
- int
scsi_internal_device_unblock_nowait(struct scsi_device * sdev, enum scsi_device_state new_state)¶ resume a device after a block request
Parameters
structscsi_device*sdev- device to resume
enumscsi_device_statenew_state- state 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.
- void *
scsi_kmap_atomic_sg(struct scatterlist * sgl, int sg_count, size_t * offset, size_t * len)¶ find and atomically map an sg-elemnt
Parameters
structscatterlist*sgl- scatter-gather list
intsg_count- number of segments in sg
size_t*offset- offset in bytes into sg, on return offset into the mapped area
size_t*len- bytes to map, on return number of bytes mapped
Description
Returns virtual address of the start of the mapped page
- void
scsi_kunmap_atomic_sg(void * virt)¶ atomically unmap a virtual address, previously mapped with scsi_kmap_atomic_sg
Parameters
void*virt- virtual address to be unmapped
- int
scsi_vpd_lun_id(struct scsi_device * sdev, char * id, size_t id_len)¶ return a unique device identification
Parameters
structscsi_device*sdev- SCSI device
char*id- buffer for the identification
size_tid_len- length 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.
drivers/scsi/scsi_lib_dma.c¶
SCSI library functions depending on DMA (map and unmap scatter-gatherlists).
- int
scsi_dma_map(struct scsi_cmnd * cmd)¶ perform DMA mapping against command’s sg lists
Parameters
structscsi_cmnd*cmd- scsi command
Description
Returns the number of sg lists actually used, zero if the sg listsis NULL, or -ENOMEM if the mapping failed.
- void
scsi_dma_unmap(struct scsi_cmnd * cmd)¶ unmap command’s sg lists mapped by scsi_dma_map
Parameters
structscsi_cmnd*cmd- scsi 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/*
- void
scsi_proc_hostdir_add(struct scsi_host_template * sht)¶ Create directory in /proc for a scsi host
Parameters
structscsi_host_template*sht- owner of this directory
Description
Sets sht->proc_dir to the new directory.
- void
scsi_proc_hostdir_rm(struct scsi_host_template * sht)¶ remove directory in /proc for a scsi host
Parameters
structscsi_host_template*sht- owner of directory
- void
scsi_proc_host_add(struct Scsi_Host * shost)¶ Add entry for this host to appropriate /proc dir
Parameters
structScsi_Host*shost- host to add
- void
scsi_proc_host_rm(struct Scsi_Host * shost)¶ remove this host’s entry from /proc
Parameters
structScsi_Host*shost- which host
Parameters
structdevice*dev- A scsi device
void*datastructseq_fileto output to.
Description
prints Host, Channel, Id, Lun, Vendor, Model, Rev, Type,and revision.
- int
scsi_add_single_device(uint host, uint channel, uint id, uint lun)¶ Respond to user request to probe for/add device
Parameters
uinthost- user-supplied decimal integer
uintchannel- user-supplied decimal integer
uintid- user-supplied decimal integer
uintlun- user-supplied decimal integer
Description
called by writing “scsi add-single-device” to /proc/scsi/scsi.
doesscsi_host_lookup() and either user_scan() if that transporttype supports it, or else scsi_scan_host_selected()
Note
this seems to be aimed exclusively at SCSI parallel busses.
- int
scsi_remove_single_device(uint host, uint channel, uint id, uint lun)¶ Respond to user request to remove a device
Parameters
uinthost- user-supplied decimal integer
uintchannel- user-supplied decimal integer
uintid- user-supplied decimal integer
uintlun- user-supplied decimal integer
Description
called by writing “scsi remove-single-device” to/proc/scsi/scsi. Does ascsi_device_lookup() andscsi_remove_device()
- ssize_t
proc_scsi_write(struct file * file, const char __user * buf, size_t length, loff_t * ppos)¶ handle writes to /proc/scsi/scsi
Parameters
structfile*file- not used
constchar__user*buf- buffer to write
size_tlength- length of buf, at most PAGE_SIZE
loff_t*ppos- not 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.
- int
proc_scsi_open(struct inode * inode, struct file * file)¶ glue function
Parameters
structinode*inode- not used
structfile*file- passed to single_open()
Description
Associates proc_scsi_show with this file
- int
scsi_init_procfs(void)¶ create scsi and scsi/scsi in procfs
Parameters
void- no arguments
- void
scsi_exit_procfs(void)¶ Remove scsi/scsi and scsi from procfs
Parameters
void- no 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 patchsubmission formore details.
Parameters
structsk_buff*skb- socket receive buffer
Description
- Extracts message from a receive buffer.
- Validates message header and calls appropriate transport message handler
- void
scsi_netlink_init(void)¶ Called by SCSI subsystem to initialize the SCSI transport netlink interface
Parameters
void- no arguments
- void
scsi_netlink_exit(void)¶ Called by SCSI subsystem to disable the SCSI transport netlink interface
Parameters
void- no 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.
- int
scsi_complete_async_scans(void)¶ Wait for asynchronous scans to complete
Parameters
void- no arguments
Description
When this function returns, any host which started scanning beforethis function was called will have finished its scan. Hosts whichstarted scanning after this function was called may or may not havefinished.
- void
scsi_unlock_floptical(struct scsi_device * sdev, unsigned char * result)¶ unlock device via a special MODE SENSE command
Parameters
structscsi_device*sdev- scsi device to send command to
unsignedchar*result- area to store the result of the MODE SENSE
Description
Send a vendor specific MODE SENSE (not a MODE SELECT) command.Called for BLIST_KEY devices.
- struct scsi_device *
scsi_alloc_sdev(struct scsi_target * starget, u64 lun, void * hostdata)¶ allocate and setup a scsi_Device
Parameters
structscsi_target*starget- which target to allocate a
scsi_devicefor u64lun- which lun
void*hostdata- usually NULL and set by ->slave_alloc instead
Description
Allocate, initialize for io, and return a pointer to a scsi_Device.Stores theshost,channel,id, andlun in the scsi_Device, andadds scsi_Device to the appropriate list.
- Return value:
- scsi_Device pointer, or NULL on failure.
- void
scsi_target_reap_ref_release(struct kref * kref)¶ remove target from visibility
Parameters
structkref*kref- the reap_ref in the target being released
Description
Called on last put of reap_ref, which is the indication that no deviceunder this target is visible anymore, so render the target invisible insysfs. Note: we have to be in user context here because the target reapsshould be done in places where the scsi device visibility is being removed.
- struct scsi_target *
scsi_alloc_target(structdevice * parent, int channel, uint id)¶ allocate a new or find an existing target
Parameters
structdevice*parent- parent of the target (need not be a scsi host)
intchannel- target channel number (zero if no channels)
uintid- target id number
Description
Return an existing target if one exists, provided it hasn’t alreadygone into STARGET_DEL state, otherwise allocate a new target.
The target is returned with an incremented reference, so the calleris responsible for both reaping and doing a last put
- void
scsi_target_reap(struct scsi_target * starget)¶ check to see if target is in use and destroy if not
Parameters
structscsi_target*starget- target to be checked
Description
This is used after removing a LUN or doing a last put of the targetit checks atomically that nothing is using the target and removesit if so.
- int
scsi_probe_lun(struct scsi_device * sdev, unsigned char * inq_result, int result_len, blist_flags_t * bflags)¶ probe a single LUN using a SCSI INQUIRY
Parameters
structscsi_device*sdev- scsi_device to probe
unsignedchar*inq_result- area to store the INQUIRY result
intresult_len- len of inq_result
blist_flags_t*bflags- store any bflags found here
Description
Probe the lun associated withreq using a standard SCSI INQUIRY;
If the INQUIRY is successful, zero is returned and theINQUIRY data is ininq_result; the scsi_level and INQUIRY lengthare copied to the scsi_device any flags value is stored in*bflags.
- int
scsi_add_lun(struct scsi_device * sdev, unsigned char * inq_result, blist_flags_t * bflags, int async)¶ allocate and fully initialze a scsi_device
Parameters
structscsi_device*sdev- holds information to be stored in the new scsi_device
unsignedchar*inq_result- holds the result of a previous INQUIRY to the LUN
blist_flags_t*bflags- black/white list flag
intasync- 1 if this device is being scanned asynchronously
Description
Initialize the scsi_devicesdev. Optionally set fields basedon values in*bflags.
Return
SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_deviceSCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
- unsigned char *
scsi_inq_str(unsigned char * buf, unsigned char * inq, unsigned first, unsigned end)¶ print INQUIRY data from min to max index, strip trailing whitespace
Parameters
unsignedchar*buf- Output buffer with at least end-first+1 bytes of space
unsignedchar*inq- Inquiry buffer (input)
unsignedfirst- Offset of string into inq
unsignedend- Index after last character in inq
- int
scsi_probe_and_add_lun(struct scsi_target * starget, u64 lun, blist_flags_t * bflagsp, struct scsi_device ** sdevp, enum scsi_scan_mode rescan, void * hostdata)¶ probe a LUN, if a LUN is found add it
Parameters
structscsi_target*starget- pointer to target device structure
u64lun- LUN of target device
blist_flags_t*bflagsp- store bflags here if not NULL
structscsi_device**sdevp- probe the LUN corresponding to this scsi_device
enumscsi_scan_moderescan- if not equal to SCSI_SCAN_INITIAL skip some code onlyneeded on first scan
void*hostdata- passed to
scsi_alloc_sdev()
Description
Call scsi_probe_lun, if a LUN with an attached device is found,allocate and set it up by calling scsi_add_lun.
Return
- SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
- SCSI_SCAN_TARGET_PRESENT: target responded, but no device is
- attached at the LUN
- SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
- void
scsi_sequential_lun_scan(struct scsi_target * starget, blist_flags_t bflags, int scsi_level, enum scsi_scan_mode rescan)¶ sequentially scan a SCSI target
Parameters
structscsi_target*starget- pointer to target structure to scan
blist_flags_tbflags- black/white list flag for LUN 0
intscsi_level- Which version of the standard does this device adhere to
enumscsi_scan_moderescan- passed to scsi_probe_add_lun()
Description
Generally, scan from LUN 1 (LUN 0 is assumed to already have beenscanned) to some maximum lun until a LUN is found with no deviceattached. Use the bflags to figure out any oddities.
Modifies sdevscan->lun.
- int
scsi_report_lun_scan(struct scsi_target * starget, blist_flags_t bflags, enum scsi_scan_mode rescan)¶ Scan using SCSI REPORT LUN results
Parameters
structscsi_target*starget- which target
blist_flags_tbflags- Zero or a mix of BLIST_NOLUN, BLIST_REPORTLUN2, or BLIST_NOREPORTLUN
enumscsi_scan_moderescan- nonzero if we can skip code only needed on first scan
Description
Fast scanning for modern (SCSI-3) devices by sending a REPORT LUN command.Scan the resulting list of LUNs by calling scsi_probe_and_add_lun.
If BLINK_REPORTLUN2 is set, scan a target that supports more than 8LUNs even if it’s older than SCSI-3.If BLIST_NOREPORTLUN is set, return 1 always.If BLIST_NOLUN is set, return 0 always.If starget->no_report_luns is set, return 1 always.
Return
0: scan completed (or no memory, so further scanning is futile)1: could not scan with REPORT LUN
- struct async_scan_data *
scsi_prep_async_scan(struct Scsi_Host * shost)¶ prepare for an async scan
Parameters
structScsi_Host*shost- the host which will be scanned
Return
a cookie to be passed toscsi_finish_async_scan()
Description
Tells the midlayer this host is going to do an asynchronous scan.It reserves the host’s position in the scanning list and ensuresthat other asynchronous scans started after this one won’t affect theordering of the discovered devices.
- void
scsi_finish_async_scan(struct async_scan_data * data)¶ asynchronous scan has finished
Parameters
structasync_scan_data*data- cookie returned from earlier call to
scsi_prep_async_scan()
Description
All the devices currently attached to this host have been found.This function announces all the devices it has found to the restof the system.
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.
- void
scsi_remove_device(struct scsi_device * sdev)¶ unregister a device from the scsi bus
Parameters
structscsi_device*sdev- scsi_device to unregister
Parameters
structdevice*dev- generic 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
- void
scsi_remove_host(struct Scsi_Host * shost)¶ remove a scsi host
Parameters
structScsi_Host*shost- a pointer to a scsi host to remove
- int
scsi_add_host_with_dma(struct Scsi_Host * shost, structdevice * dev, structdevice * dma_dev)¶ add a scsi host with dma device
Parameters
structScsi_Host*shost- scsi host pointer to add
structdevice*dev- a struct device of type scsi class
structdevice*dma_dev- dma device for the host
Note
You rarely need to worry about this unless you’re in avirtualised host environments, so use the simpler scsi_add_host()function instead.
Description
- Return value:
- 0 on success / != 0 for error
- struct Scsi_Host *
scsi_host_alloc(struct scsi_host_template * sht, int privsize)¶ register a scsi host adapter instance.
Parameters
structscsi_host_template*sht- pointer to scsi host template
intprivsize- extra 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.
Description
- Return value:
- Pointer to a new Scsi_Host
- struct Scsi_Host *
scsi_host_lookup(unsigned short hostnum)¶ get a reference to a Scsi_Host by host no
Parameters
unsignedshorthostnum- host 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().
- struct Scsi_Host *
scsi_host_get(struct Scsi_Host * shost)¶ inc a Scsi_Host ref count
Parameters
structScsi_Host*shost- Pointer to Scsi_Host to inc.
- int
scsi_host_busy(struct Scsi_Host * shost)¶ Return the host busy counter
Parameters
structScsi_Host*shost- Pointer to Scsi_Host to inc.
- void
scsi_host_put(struct Scsi_Host * shost)¶ dec a Scsi_Host ref count
Parameters
structScsi_Host*shost- Pointer to Scsi_Host to dec.
- int
scsi_queue_work(struct Scsi_Host * shost, struct work_struct * work)¶ Queue work to the Scsi_Host workqueue.
Parameters
structScsi_Host*shost- Pointer to Scsi_Host.
structwork_struct*work- Work to queue for execution.
Description
- Return value:
- 1 - work queued for execution0 - work is already queued-EINVAL - work queue doesn’t exist
- void
scsi_flush_work(struct Scsi_Host * shost)¶ Flush a Scsi_Host’s workqueue.
Parameters
structScsi_Host*shost- Pointer to Scsi_Host.
- void
scsi_host_complete_all_commands(struct Scsi_Host * shost, int status)¶ Terminate all running commands
Parameters
structScsi_Host*shost- Scsi Host on which commands should be terminated
intstatus- Status 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.
- void
scsi_host_busy_iter(struct Scsi_Host * shost, bool (*fn)(struct scsi_cmnd *, void *, bool), void * priv)¶ Iterate over all busy commands
Parameters
structScsi_Host*shost- Pointer to Scsi_Host.
bool(*)(structscsi_cmnd*,void*,bool)fn- Function to call on each busy command
void*priv- Data 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
- const char *
scsi_device_type(unsigned type)¶ Return 17-char string indicating device type.
Parameters
unsignedtype- type number to look up
- u64
scsilun_to_int(struct scsi_lun * scsilun)¶ convert a scsi_lun to an int
Parameters
structscsi_lun*scsilun- struct scsi_lun to be converted.
Description
Convertscsilun from a struct scsi_lun to 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 struct scsi_lun of: d2 04 0b 03 00 00 00 00, this functionreturns the integer: 0x0b03d204
This encoding will return a standard integer LUN for LUNs smallerthan 256, which typically use a single level LUN structure withaddressing method 0.
- void
int_to_scsilun(u64 lun, struct scsi_lun * scsilun)¶ reverts an int into a scsi_lun
Parameters
u64lun- integer to be reverted
structscsi_lun*scsilun- struct scsi_lun to 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 astruct scsi_lun of: d2 04 0b 03 00 00 00 00
- bool
scsi_normalize_sense(const u8 * sense_buffer, int sb_len, struct scsi_sense_hdr * sshdr)¶ normalize main elements from either fixed or descriptor sense data format into a common format.
Parameters
constu8*sense_buffer- byte array containing sense data returned by device
intsb_len- number of valid bytes in sense_buffer
structscsi_sense_hdr*sshdr- pointer 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.
Description
- Return value:
- true if valid sense data information found, else false;
- const u8 *
scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, int desc_type)¶ search for a given descriptor type in descriptor sense data format.
Parameters
constu8*sense_buffer- byte array of descriptor format sense data
intsb_len- number of valid bytes in sense_buffer
intdesc_type- value of descriptor type to find(e.g. 0 -> information)
Notes
only valid when sense data is in descriptor format
Description
- Return value:
- pointer to start of (first) descriptor if found else NULL
- void
scsi_build_sense_buffer(int desc, u8 * buf, u8 key, u8 asc, u8 ascq)¶ build sense data in a buffer
Parameters
intdesc- Sense format (non-zero == descriptor format,0 == fixed format)
u8*buf- Where to build sense data
u8key- Sense key
u8asc- Additional sense code
u8ascq- Additional sense code qualifier
- int
scsi_set_sense_information(u8 * buf, int buf_len, u64 info)¶ set the information field in a formatted sense data buffer
Parameters
u8*buf- Where to build sense data
intbuf_len- buffer length
u64info- 64-bit information value to be set
Description
- Return value:
- 0 on success or -EINVAL for invalid sense buffer length
- int
scsi_set_sense_field_pointer(u8 * buf, int buf_len, u16 fp, u8 bp, bool cd)¶ set the field pointer sense key specific information in a formatted sense data buffer
Parameters
u8*buf- Where to build sense data
intbuf_len- buffer length
u16fp- field pointer to be set
u8bp- bit pointer to be set
boolcd- command/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.
- u32
fc_get_event_number(void)¶ Obtain the next sequential FC event number
Parameters
void- no 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…
- void
fc_host_post_fc_event(struct Scsi_Host * shost, u32 event_number, enum fc_host_event_code event_code, u32 data_len, char * data_buf, u64 vendor_id)¶ routine to do the work of posting an event on an fc_host.
Parameters
structScsi_Host*shost- host the event occurred on
u32event_number- fc event number obtained from get_fc_event_number()
enumfc_host_event_codeevent_code- fc_host event being posted
u32data_len- amount, in bytes, of event data
char*data_buf- pointer to event data
u64vendor_id- value for Vendor id
Notes
This routine assumes no locks are held on entry.
- void
fc_host_post_event(struct Scsi_Host * shost, u32 event_number, enum fc_host_event_code event_code, u32 event_data)¶ called to post an even on an fc_host.
Parameters
structScsi_Host*shost- host the event occurred on
u32event_number- fc event number obtained from get_fc_event_number()
enumfc_host_event_codeevent_code- fc_host event being posted
u32event_data- 32bits of data for the event being posted
Notes
This routine assumes no locks are held on entry.
- void
fc_host_post_vendor_event(struct Scsi_Host * shost, u32 event_number, u32 data_len, char * data_buf, u64 vendor_id)¶ called to post a vendor unique event on an fc_host
Parameters
structScsi_Host*shost- host the event occurred on
u32event_number- fc event number obtained from get_fc_event_number()
u32data_len- amount, in bytes, of vendor unique data
char*data_buf- pointer to vendor unique data
u64vendor_id- Vendor id
Notes
This routine assumes no locks are held on entry.
- void
fc_host_fpin_rcv(struct Scsi_Host * shost, u32 fpin_len, char * fpin_buf)¶ routine to process a received FPIN.
Parameters
structScsi_Host*shost- host the FPIN was received on
u32fpin_len- length of FPIN payload, in bytes
char*fpin_buf- pointer to FPIN payload
Notes
This routine assumes no locks are held on entry.
- enum blk_eh_timer_return
fc_eh_timed_out(struct scsi_cmnd * scmd)¶ FC Transport I/O timeout intercept handler
Parameters
structscsi_cmnd*scmd- The 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.
- void
fc_remove_host(struct Scsi_Host * shost)¶ called to terminate any fc_transport-related elements for a scsi host.
Parameters
structScsi_Host*shost- Which
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.
- struct fc_rport *
fc_remote_port_add(struct Scsi_Host * shost, int channel, struct fc_rport_identifiers * ids)¶ notify fc transport of the existence of a remote FC port.
Parameters
structScsi_Host*shost- scsi host the remote port is connected to.
intchannel- Channel on shost port connected to.
structfc_rport_identifiers*ids- The 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.
- void
fc_remote_port_delete(struct fc_rport * rport)¶ notifies the fc transport that a remote port is no longer in existence.
Parameters
structfc_rport*rport- The 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.
- void
fc_remote_port_rolechg(struct fc_rport * rport, u32 roles)¶ notifies the fc transport that the roles on a remote may have changed.
Parameters
structfc_rport*rport- The remote port that changed.
u32roles- New 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.
- int
fc_block_rport(struct fc_rport * rport)¶ Block SCSI eh thread for blocked fc_rport.
Parameters
structfc_rport*rport- Remote 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.
- int
fc_block_scsi_eh(struct scsi_cmnd * cmnd)¶ Block SCSI eh thread for blocked fc_rport
Parameters
structscsi_cmnd*cmnd- SCSI 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.
- struct fc_vport *
fc_vport_create(struct Scsi_Host * shost, int channel, struct fc_vport_identifiers * ids)¶ Admin App or LLDD requests creation of a vport
Parameters
structScsi_Host*shost- scsi host the virtual port is connected to.
intchannel- channel on shost port connected to.
structfc_vport_identifiers*ids- The world wide names, FC4 port roles, etc forthe virtual port.
Notes
This routine assumes no locks are held on entry.
- int
fc_vport_terminate(struct fc_vport * vport)¶ Admin App or LLDD requests termination of a vport
Parameters
structfc_vport*vport- fc_vport to be terminated
Description
Calls the LLDD vport_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.
- struct iscsi_bus_flash_session *
iscsi_create_flashnode_sess(struct Scsi_Host * shost, int index, struct iscsi_transport * transport, int dd_size)¶ Add flashnode session entry in sysfs
Parameters
structScsi_Host*shost- pointer to host data
intindex- index of flashnode to add in sysfs
structiscsi_transport*transport- pointer to transport data
intdd_size- total size to allocate
Description
Adds a sysfs entry for the flashnode session attributes
Return
pointer to allocated flashnode sess on successNULLon failure
- struct iscsi_bus_flash_conn *
iscsi_create_flashnode_conn(struct Scsi_Host * shost, struct iscsi_bus_flash_session * fnode_sess, struct iscsi_transport * transport, int dd_size)¶ Add flashnode conn entry in sysfs
Parameters
structScsi_Host*shost- pointer to host data
structiscsi_bus_flash_session*fnode_sess- pointer to the parent flashnode session entry
structiscsi_transport*transport- pointer to transport data
intdd_size- total size to allocate
Description
Adds a sysfs entry for the flashnode connection attributes
Return
pointer to allocated flashnode conn on successNULLon failure
- structdevice *
iscsi_find_flashnode_sess(struct Scsi_Host * shost, void * data, int (*fn)(structdevice *dev, void *data))¶ finds flashnode session entry
Parameters
structScsi_Host*shost- pointer to host data
void*data- pointer to data containing value to use for comparison
int(*)(structdevice*dev,void*data)fn- function 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 successNULLon failure
- structdevice *
iscsi_find_flashnode_conn(struct iscsi_bus_flash_session * fnode_sess)¶ finds flashnode connection entry
Parameters
structiscsi_bus_flash_session*fnode_sess- pointer 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 successNULLon failure
- void
iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session * fnode_sess)¶ destroy flashnode session entry
Parameters
structiscsi_bus_flash_session*fnode_sess- pointer to flashnode session entry to be destroyed
Description
Deletes the flashnode session entry and all children flashnode connectionentries from sysfs
- void
iscsi_destroy_all_flashnode(struct Scsi_Host * shost)¶ destroy all flashnode session entries
Parameters
structScsi_Host*shost- pointer to host data
Description
Destroys all the flashnode session entries and all corresponding childrenflashnode connection entries from sysfs
- int
iscsi_scan_finished(struct Scsi_Host * shost, unsigned long time)¶ helper to report when running scans are done
Parameters
structScsi_Host*shost- scsi host
unsignedlongtime- scan run time
Description
This function can be used by drives like qla4xxx to report to the scsilayer when the scans it kicked off at module load time are done.
- int
iscsi_block_scsi_eh(struct scsi_cmnd * cmd)¶ block scsi eh until session state has transistioned
Parameters
structscsi_cmnd*cmd- scsi 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.
- void
iscsi_unblock_session(struct iscsi_cls_session * session)¶ set a session as logged in and start IO.
Parameters
structiscsi_cls_session*session- iscsi session
Description
Mark a session as ready to accept IO.
- struct iscsi_cls_session *
iscsi_create_session(struct Scsi_Host * shost, struct iscsi_transport * transport, int dd_size, unsigned int target_id)¶ create iscsi class session
Parameters
structScsi_Host*shost- scsi host
structiscsi_transport*transport- iscsi transport
intdd_size- private driver data size
unsignedinttarget_id- which target
Description
This can be called from a LLD or iscsi_transport.
- struct iscsi_cls_conn *
iscsi_create_conn(struct iscsi_cls_session * session, int dd_size, uint32_t cid)¶ create iscsi class connection
Parameters
structiscsi_cls_session*session- iscsi cls session
intdd_size- private driver data size
uint32_tcid- connection id
Description
This can be called from a LLD or iscsi_transport. The connectionis child of the session so cid must be unique for all connectionson the session.
Since we do not support MCS, cid will normally be zero. In some casesfor software iscsi we could be trying to preallocate a connection structin which case there could be two connection structs and cid would benon-zero.
- int
iscsi_destroy_conn(struct iscsi_cls_conn * conn)¶ destroy iscsi class connection
Parameters
structiscsi_cls_conn*conn- iscsi cls session
Description
This can be called from a LLD or iscsi_transport.
- int
iscsi_session_event(struct iscsi_cls_session * session, enum iscsi_uevent_e event)¶ send session destr. completion event
Parameters
structiscsi_cls_session*session- iscsi class session
enumiscsi_uevent_eevent- type 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, anaproximated 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 by struct sas_phy defines an “outgoing” PHY on a SAS HBA orExpander, and the SAS remote PHY represented by struct sas_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*dev- device belonging to the sas object
Description
Removes all SAS PHYs and remote PHYs for a given object
- void
sas_remove_host(struct Scsi_Host * shost)¶ tear down a Scsi_Host’s SAS data structures
Parameters
structScsi_Host*shost- Scsi 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.
- u64
sas_get_address(struct scsi_device * sdev)¶ return the SAS address of the device
Parameters
structscsi_device*sdev- scsi device
Description
Returns the SAS address of the scsi device
- unsigned int
sas_tlr_supported(struct scsi_device * sdev)¶ checking TLR bit in vpd 0x90
Parameters
structscsi_device*sdev- scsi device struct
Description
Check Transport Layer Retries are supported or not.If vpd page 0x90 is present, TRL is supported.
- void
sas_disable_tlr(struct scsi_device * sdev)¶ setting TLR flags
Parameters
structscsi_device*sdev- scsi device struct
Description
Seting tlr_enabled flag to 0.
- void
sas_enable_tlr(struct scsi_device * sdev)¶ setting TLR flags
Parameters
structscsi_device*sdev- scsi device struct
Description
Seting tlr_enabled flag 1.
- struct sas_phy *
sas_phy_alloc(structdevice * parent, int number)¶ allocates and initialize a SAS PHY structure
Parameters
structdevice*parent- Parent device
intnumber- Phy 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 orNULLif the allocation failed.
- int
sas_phy_add(struct sas_phy * phy)¶ add a SAS PHY to the device hierarchy
Parameters
structsas_phy*phy- The PHY to be added
Description
Publishes a SAS PHY to the rest of the system.
- void
sas_phy_free(struct sas_phy * phy)¶ free a SAS PHY
Parameters
structsas_phy*phy- SAS PHY to free
Description
Frees the specified SAS PHY.
Note
This function must only be called on a PHY that has notsuccessfully been added usingsas_phy_add().
- void
sas_phy_delete(struct sas_phy * phy)¶ remove SAS PHY
Parameters
structsas_phy*phy- SAS PHY to remove
Description
Removes the specified SAS PHY. If the SAS PHY has anassociated remote PHY it is removed before.
Parameters
conststructdevice*dev- device to check
Return
1if the device represents a SAS PHY,0else
- int
sas_port_add(struct sas_port * port)¶ add a SAS port to the device hierarchy
Parameters
structsas_port*port- port to be added
Description
publishes a port to the rest of the system
- void
sas_port_free(struct sas_port * port)¶ free a SAS PORT
Parameters
structsas_port*port- SAS PORT to free
Description
Frees the specified SAS PORT.
Note
This function must only be called on a PORT that has notsuccessfully been added usingsas_port_add().
- void
sas_port_delete(struct sas_port * port)¶ remove SAS PORT
Parameters
structsas_port*port- SAS PORT to remove
Description
Removes the specified SAS PORT. If the SAS PORT has anassociated phys, unlink them from the port as well.
Parameters
conststructdevice*dev- device to check
Return
1if the device represents a SAS Port,0else
- struct sas_phy *
sas_port_get_phy(struct sas_port * port)¶ try to take a reference on a port member
Parameters
structsas_port*port- port to check
- void
sas_port_add_phy(struct sas_port * port, struct sas_phy * phy)¶ add another phy to a port to form a wide port
Parameters
structsas_port*port- port to add the phy to
structsas_phy*phy- phy 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.
- void
sas_port_delete_phy(struct sas_port * port, struct sas_phy * phy)¶ remove a phy from a port or wide port
Parameters
structsas_port*port- port to remove the phy from
structsas_phy*phy- phy 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.
- struct sas_rphy *
sas_end_device_alloc(struct sas_port * parent)¶ allocate an rphy for an end device
Parameters
structsas_port*parent- which port
Description
Allocates an SAS remote PHY structure, connected toparent.
Return
SAS PHY allocated orNULLif the allocation failed.
- struct sas_rphy *
sas_expander_alloc(struct sas_port * parent, enum sas_device_type type)¶ allocate an rphy for an end device
Parameters
structsas_port*parent- which port
enumsas_device_typetype- SAS_EDGE_EXPANDER_DEVICE or SAS_FANOUT_EXPANDER_DEVICE
Description
Allocates an SAS remote PHY structure, connected toparent.
Return
SAS PHY allocated orNULLif the allocation failed.
- int
sas_rphy_add(struct sas_rphy * rphy)¶ add a SAS remote PHY to the device hierarchy
Parameters
structsas_rphy*rphy- The remote PHY to be added
Description
Publishes a SAS remote PHY to the rest of the system.
- void
sas_rphy_free(struct sas_rphy * rphy)¶ free a SAS remote PHY
Parameters
structsas_rphy*rphy- SAS 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 usingsas_rphy_add()(or has beensas_rphy_remove()’d)
- void
sas_rphy_delete(struct sas_rphy * rphy)¶ remove and free SAS remote PHY
Parameters
structsas_rphy*rphy- SAS remote PHY to remove and free
Description
Removes the specified SAS remote PHY and frees it.
- void
sas_rphy_unlink(struct sas_rphy * rphy)¶ unlink SAS remote PHY
Parameters
structsas_rphy*rphy- SAS remote phy to unlink from its parent port
Description
Removes port reference to an rphy
- void
sas_rphy_remove(struct sas_rphy * rphy)¶ remove SAS remote PHY
Parameters
structsas_rphy*rphy- SAS remote phy to remove
Description
Removes the specified SAS remote PHY.
Parameters
conststructdevice*dev- device to check
Return
1if the device represents a SAS remote PHY,0else
- struct scsi_transport_template *
sas_attach_transport(struct sas_function_template * ft)¶ instantiate SAS transport template
Parameters
structsas_function_template*ft- SAS transport class function template
- void
sas_release_transport(struct scsi_transport_template * t)¶ release SAS transport template instance
Parameters
structscsi_transport_template*t- transport 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 busses.
- void
spi_schedule_dv_device(struct scsi_device * sdev)¶ schedule domain validation to occur on the device
Parameters
structscsi_device*sdevThe device to validate
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.
- void
spi_display_xfer_agreement(struct scsi_target * starget)¶ Print the current target transfer agreement
Parameters
structscsi_target*starget- The 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.
- int
spi_populate_tag_msg(unsigned char * msg, struct scsi_cmnd * cmd)¶ place a tag message in a buffer
Parameters
unsignedchar*msg- pointer to the area to place the tag
structscsi_cmnd*cmd- pointer 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.
- int
srp_tmo_valid(int reconnect_delay, int fast_io_fail_tmo, long dev_loss_tmo)¶ check timeout combination validity
Parameters
intreconnect_delay- Reconnect delay in seconds.
intfast_io_fail_tmo- Fast I/O fail timeout in seconds.
longdev_loss_tmo- Device 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.
- void
srp_start_tl_fail_timers(struct srp_rport * rport)¶ start the transport layer failure timers
Parameters
structsrp_rport*rport- SRP target port.
Description
Start the transport layer fast I/O failure and device loss timers. Do notmodify a timer that was already started.
- int
srp_reconnect_rport(struct srp_rport * rport)¶ reconnect to an SRP target port
Parameters
structsrp_rport*rport- SRP target port.
Description
Blocks SCSI command queueing before invoking reconnect() such thatqueuecommand() won’t be invoked concurrently with reconnect() from outsidethe SCSI EH. This is important since a reconnect() implementation mayreallocate resources needed by queuecommand().
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).
- enum blk_eh_timer_return
srp_timed_out(struct scsi_cmnd * scmd)¶ SRP transport intercept of the SCSI timeout EH
Parameters
structscsi_cmnd*scmd- SCSI command.
Description
If a timeout occurs while an rport is in the blocked state, ask the SCSIEH to continue waiting (BLK_EH_RESET_TIMER). Otherwise let the SCSI corehandle the timeout (BLK_EH_DONE).
Note
This function is called from soft-IRQ context and with the requestqueue lock held.
- void
srp_rport_get(struct srp_rport * rport)¶ increment rport reference count
Parameters
structsrp_rport*rport- SRP target port.
- void
srp_rport_put(struct srp_rport * rport)¶ decrement rport reference count
Parameters
structsrp_rport*rport- SRP target port.
- struct srp_rport *
srp_rport_add(struct Scsi_Host * shost, struct srp_rport_identifiers * ids)¶ add a SRP remote port to the device hierarchy
Parameters
structScsi_Host*shost- scsi host the remote port is connected to.
structsrp_rport_identifiers*ids- The port id for the remote port.
Description
Publishes a port to the rest of the system.
- void
srp_rport_del(struct srp_rport * rport)¶ remove a SRP remote port
Parameters
structsrp_rport*rport- SRP remote port to remove
Description
Removes the specified SRP remote port.
- void
srp_remove_host(struct Scsi_Host * shost)¶ tear down a Scsi_Host’s SRP data structures
Parameters
structScsi_Host*shost- Scsi 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.
- void
srp_stop_rport_timers(struct srp_rport * rport)¶ stop the transport layer recovery timers
Parameters
structsrp_rport*rport- SRP 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).
- struct scsi_transport_template *
srp_attach_transport(struct srp_function_template * ft)¶ instantiate SRP transport template
Parameters
structsrp_function_template*ft- SRP transport class function template
- void
srp_release_transport(struct scsi_transport_template * t)¶ release SRP transport template instance
Parameters
structscsi_transport_template*t- transport 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/sdebug26.html
todo¶
Parallel (fast/wide/ultra) SCSI, USB, SATA, SAS, Fibre Channel,FireWire, ATAPI devices, Infiniband, I2O, Parallel ports,netlink…