162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _SCSI_SCSI_DEVICE_H 362306a36Sopenharmony_ci#define _SCSI_SCSI_DEVICE_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/list.h> 662306a36Sopenharmony_ci#include <linux/spinlock.h> 762306a36Sopenharmony_ci#include <linux/workqueue.h> 862306a36Sopenharmony_ci#include <linux/blk-mq.h> 962306a36Sopenharmony_ci#include <scsi/scsi.h> 1062306a36Sopenharmony_ci#include <linux/atomic.h> 1162306a36Sopenharmony_ci#include <linux/sbitmap.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistruct bsg_device; 1462306a36Sopenharmony_cistruct device; 1562306a36Sopenharmony_cistruct request_queue; 1662306a36Sopenharmony_cistruct scsi_cmnd; 1762306a36Sopenharmony_cistruct scsi_lun; 1862306a36Sopenharmony_cistruct scsi_sense_hdr; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_citypedef __u64 __bitwise blist_flags_t; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define SCSI_SENSE_BUFFERSIZE 96 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistruct scsi_mode_data { 2562306a36Sopenharmony_ci __u32 length; 2662306a36Sopenharmony_ci __u16 block_descriptor_length; 2762306a36Sopenharmony_ci __u8 medium_type; 2862306a36Sopenharmony_ci __u8 device_specific; 2962306a36Sopenharmony_ci __u8 header_length; 3062306a36Sopenharmony_ci __u8 longlba:1; 3162306a36Sopenharmony_ci}; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* 3462306a36Sopenharmony_ci * sdev state: If you alter this, you also need to alter scsi_sysfs.c 3562306a36Sopenharmony_ci * (for the ascii descriptions) and the state model enforcer: 3662306a36Sopenharmony_ci * scsi_lib:scsi_device_set_state(). 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_cienum scsi_device_state { 3962306a36Sopenharmony_ci SDEV_CREATED = 1, /* device created but not added to sysfs 4062306a36Sopenharmony_ci * Only internal commands allowed (for inq) */ 4162306a36Sopenharmony_ci SDEV_RUNNING, /* device properly configured 4262306a36Sopenharmony_ci * All commands allowed */ 4362306a36Sopenharmony_ci SDEV_CANCEL, /* beginning to delete device 4462306a36Sopenharmony_ci * Only error handler commands allowed */ 4562306a36Sopenharmony_ci SDEV_DEL, /* device deleted 4662306a36Sopenharmony_ci * no commands allowed */ 4762306a36Sopenharmony_ci SDEV_QUIESCE, /* Device quiescent. No block commands 4862306a36Sopenharmony_ci * will be accepted, only specials (which 4962306a36Sopenharmony_ci * originate in the mid-layer) */ 5062306a36Sopenharmony_ci SDEV_OFFLINE, /* Device offlined (by error handling or 5162306a36Sopenharmony_ci * user request */ 5262306a36Sopenharmony_ci SDEV_TRANSPORT_OFFLINE, /* Offlined by transport class error handler */ 5362306a36Sopenharmony_ci SDEV_BLOCK, /* Device blocked by scsi lld. No 5462306a36Sopenharmony_ci * scsi commands from user or midlayer 5562306a36Sopenharmony_ci * should be issued to the scsi 5662306a36Sopenharmony_ci * lld. */ 5762306a36Sopenharmony_ci SDEV_CREATED_BLOCK, /* same as above but for created devices */ 5862306a36Sopenharmony_ci}; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cienum scsi_scan_mode { 6162306a36Sopenharmony_ci SCSI_SCAN_INITIAL = 0, 6262306a36Sopenharmony_ci SCSI_SCAN_RESCAN, 6362306a36Sopenharmony_ci SCSI_SCAN_MANUAL, 6462306a36Sopenharmony_ci}; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cienum scsi_device_event { 6762306a36Sopenharmony_ci SDEV_EVT_MEDIA_CHANGE = 1, /* media has changed */ 6862306a36Sopenharmony_ci SDEV_EVT_INQUIRY_CHANGE_REPORTED, /* 3F 03 UA reported */ 6962306a36Sopenharmony_ci SDEV_EVT_CAPACITY_CHANGE_REPORTED, /* 2A 09 UA reported */ 7062306a36Sopenharmony_ci SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED, /* 38 07 UA reported */ 7162306a36Sopenharmony_ci SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED, /* 2A 01 UA reported */ 7262306a36Sopenharmony_ci SDEV_EVT_LUN_CHANGE_REPORTED, /* 3F 0E UA reported */ 7362306a36Sopenharmony_ci SDEV_EVT_ALUA_STATE_CHANGE_REPORTED, /* 2A 06 UA reported */ 7462306a36Sopenharmony_ci SDEV_EVT_POWER_ON_RESET_OCCURRED, /* 29 00 UA reported */ 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci SDEV_EVT_FIRST = SDEV_EVT_MEDIA_CHANGE, 7762306a36Sopenharmony_ci SDEV_EVT_LAST = SDEV_EVT_POWER_ON_RESET_OCCURRED, 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci SDEV_EVT_MAXBITS = SDEV_EVT_LAST + 1 8062306a36Sopenharmony_ci}; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistruct scsi_event { 8362306a36Sopenharmony_ci enum scsi_device_event evt_type; 8462306a36Sopenharmony_ci struct list_head node; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci /* put union of data structures, for non-simple event types, 8762306a36Sopenharmony_ci * here 8862306a36Sopenharmony_ci */ 8962306a36Sopenharmony_ci}; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci/** 9262306a36Sopenharmony_ci * struct scsi_vpd - SCSI Vital Product Data 9362306a36Sopenharmony_ci * @rcu: For kfree_rcu(). 9462306a36Sopenharmony_ci * @len: Length in bytes of @data. 9562306a36Sopenharmony_ci * @data: VPD data as defined in various T10 SCSI standard documents. 9662306a36Sopenharmony_ci */ 9762306a36Sopenharmony_cistruct scsi_vpd { 9862306a36Sopenharmony_ci struct rcu_head rcu; 9962306a36Sopenharmony_ci int len; 10062306a36Sopenharmony_ci unsigned char data[]; 10162306a36Sopenharmony_ci}; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_cistruct scsi_device { 10462306a36Sopenharmony_ci struct Scsi_Host *host; 10562306a36Sopenharmony_ci struct request_queue *request_queue; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci /* the next two are protected by the host->host_lock */ 10862306a36Sopenharmony_ci struct list_head siblings; /* list of all devices on this host */ 10962306a36Sopenharmony_ci struct list_head same_target_siblings; /* just the devices sharing same target id */ 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci struct sbitmap budget_map; 11262306a36Sopenharmony_ci atomic_t device_blocked; /* Device returned QUEUE_FULL. */ 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci atomic_t restarts; 11562306a36Sopenharmony_ci spinlock_t list_lock; 11662306a36Sopenharmony_ci struct list_head starved_entry; 11762306a36Sopenharmony_ci unsigned short queue_depth; /* How deep of a queue we want */ 11862306a36Sopenharmony_ci unsigned short max_queue_depth; /* max queue depth */ 11962306a36Sopenharmony_ci unsigned short last_queue_full_depth; /* These two are used by */ 12062306a36Sopenharmony_ci unsigned short last_queue_full_count; /* scsi_track_queue_full() */ 12162306a36Sopenharmony_ci unsigned long last_queue_full_time; /* last queue full time */ 12262306a36Sopenharmony_ci unsigned long queue_ramp_up_period; /* ramp up period in jiffies */ 12362306a36Sopenharmony_ci#define SCSI_DEFAULT_RAMP_UP_PERIOD (120 * HZ) 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci unsigned long last_queue_ramp_up; /* last queue ramp up time */ 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci unsigned int id, channel; 12862306a36Sopenharmony_ci u64 lun; 12962306a36Sopenharmony_ci unsigned int manufacturer; /* Manufacturer of device, for using 13062306a36Sopenharmony_ci * vendor-specific cmd's */ 13162306a36Sopenharmony_ci unsigned sector_size; /* size in bytes */ 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci void *hostdata; /* available to low-level driver */ 13462306a36Sopenharmony_ci unsigned char type; 13562306a36Sopenharmony_ci char scsi_level; 13662306a36Sopenharmony_ci char inq_periph_qual; /* PQ from INQUIRY data */ 13762306a36Sopenharmony_ci struct mutex inquiry_mutex; 13862306a36Sopenharmony_ci unsigned char inquiry_len; /* valid bytes in 'inquiry' */ 13962306a36Sopenharmony_ci unsigned char * inquiry; /* INQUIRY response data */ 14062306a36Sopenharmony_ci const char * vendor; /* [back_compat] point into 'inquiry' ... */ 14162306a36Sopenharmony_ci const char * model; /* ... after scan; point to static string */ 14262306a36Sopenharmony_ci const char * rev; /* ... "nullnullnullnull" before scan */ 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci#define SCSI_DEFAULT_VPD_LEN 255 /* default SCSI VPD page size (max) */ 14562306a36Sopenharmony_ci struct scsi_vpd __rcu *vpd_pg0; 14662306a36Sopenharmony_ci struct scsi_vpd __rcu *vpd_pg83; 14762306a36Sopenharmony_ci struct scsi_vpd __rcu *vpd_pg80; 14862306a36Sopenharmony_ci struct scsi_vpd __rcu *vpd_pg89; 14962306a36Sopenharmony_ci struct scsi_vpd __rcu *vpd_pgb0; 15062306a36Sopenharmony_ci struct scsi_vpd __rcu *vpd_pgb1; 15162306a36Sopenharmony_ci struct scsi_vpd __rcu *vpd_pgb2; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci struct scsi_target *sdev_target; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci blist_flags_t sdev_bflags; /* black/white flags as also found in 15662306a36Sopenharmony_ci * scsi_devinfo.[hc]. For now used only to 15762306a36Sopenharmony_ci * pass settings from slave_alloc to scsi 15862306a36Sopenharmony_ci * core. */ 15962306a36Sopenharmony_ci unsigned int eh_timeout; /* Error handling timeout */ 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci /* 16262306a36Sopenharmony_ci * If true, let the high-level device driver (sd) manage the device 16362306a36Sopenharmony_ci * power state for system suspend/resume (suspend to RAM and 16462306a36Sopenharmony_ci * hibernation) operations. 16562306a36Sopenharmony_ci */ 16662306a36Sopenharmony_ci unsigned manage_system_start_stop:1; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci /* 16962306a36Sopenharmony_ci * If true, let the high-level device driver (sd) manage the device 17062306a36Sopenharmony_ci * power state for runtime device suspand and resume operations. 17162306a36Sopenharmony_ci */ 17262306a36Sopenharmony_ci unsigned manage_runtime_start_stop:1; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci /* 17562306a36Sopenharmony_ci * If true, let the high-level device driver (sd) manage the device 17662306a36Sopenharmony_ci * power state for system shutdown (power off) operations. 17762306a36Sopenharmony_ci */ 17862306a36Sopenharmony_ci unsigned manage_shutdown:1; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci /* 18162306a36Sopenharmony_ci * If set and if the device is runtime suspended, ask the high-level 18262306a36Sopenharmony_ci * device driver (sd) to force a runtime resume of the device. 18362306a36Sopenharmony_ci */ 18462306a36Sopenharmony_ci unsigned force_runtime_start_on_system_start:1; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci unsigned removable:1; 18762306a36Sopenharmony_ci unsigned changed:1; /* Data invalid due to media change */ 18862306a36Sopenharmony_ci unsigned busy:1; /* Used to prevent races */ 18962306a36Sopenharmony_ci unsigned lockable:1; /* Able to prevent media removal */ 19062306a36Sopenharmony_ci unsigned locked:1; /* Media removal disabled */ 19162306a36Sopenharmony_ci unsigned borken:1; /* Tell the Seagate driver to be 19262306a36Sopenharmony_ci * painfully slow on this device */ 19362306a36Sopenharmony_ci unsigned disconnect:1; /* can disconnect */ 19462306a36Sopenharmony_ci unsigned soft_reset:1; /* Uses soft reset option */ 19562306a36Sopenharmony_ci unsigned sdtr:1; /* Device supports SDTR messages */ 19662306a36Sopenharmony_ci unsigned wdtr:1; /* Device supports WDTR messages */ 19762306a36Sopenharmony_ci unsigned ppr:1; /* Device supports PPR messages */ 19862306a36Sopenharmony_ci unsigned tagged_supported:1; /* Supports SCSI-II tagged queuing */ 19962306a36Sopenharmony_ci unsigned simple_tags:1; /* simple queue tag messages are enabled */ 20062306a36Sopenharmony_ci unsigned was_reset:1; /* There was a bus reset on the bus for 20162306a36Sopenharmony_ci * this device */ 20262306a36Sopenharmony_ci unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN 20362306a36Sopenharmony_ci * because we did a bus reset. */ 20462306a36Sopenharmony_ci unsigned use_10_for_rw:1; /* first try 10-byte read / write */ 20562306a36Sopenharmony_ci unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ 20662306a36Sopenharmony_ci unsigned set_dbd_for_ms:1; /* Set "DBD" field in mode sense */ 20762306a36Sopenharmony_ci unsigned read_before_ms:1; /* perform a READ before MODE SENSE */ 20862306a36Sopenharmony_ci unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ 20962306a36Sopenharmony_ci unsigned no_write_same:1; /* no WRITE SAME command */ 21062306a36Sopenharmony_ci unsigned use_16_for_rw:1; /* Use read/write(16) over read/write(10) */ 21162306a36Sopenharmony_ci unsigned use_16_for_sync:1; /* Use sync (16) over sync (10) */ 21262306a36Sopenharmony_ci unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ 21362306a36Sopenharmony_ci unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ 21462306a36Sopenharmony_ci unsigned skip_vpd_pages:1; /* do not read VPD pages */ 21562306a36Sopenharmony_ci unsigned try_vpd_pages:1; /* attempt to read VPD pages */ 21662306a36Sopenharmony_ci unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ 21762306a36Sopenharmony_ci unsigned no_start_on_add:1; /* do not issue start on add */ 21862306a36Sopenharmony_ci unsigned allow_restart:1; /* issue START_UNIT in error handler */ 21962306a36Sopenharmony_ci unsigned no_start_on_resume:1; /* Do not issue START_STOP_UNIT on resume */ 22062306a36Sopenharmony_ci unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */ 22162306a36Sopenharmony_ci unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ 22262306a36Sopenharmony_ci unsigned select_no_atn:1; 22362306a36Sopenharmony_ci unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ 22462306a36Sopenharmony_ci unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */ 22562306a36Sopenharmony_ci unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ 22662306a36Sopenharmony_ci unsigned last_sector_bug:1; /* do not use multisector accesses on 22762306a36Sopenharmony_ci SD_LAST_BUGGY_SECTORS */ 22862306a36Sopenharmony_ci unsigned no_read_disc_info:1; /* Avoid READ_DISC_INFO cmds */ 22962306a36Sopenharmony_ci unsigned no_read_capacity_16:1; /* Avoid READ_CAPACITY_16 cmds */ 23062306a36Sopenharmony_ci unsigned try_rc_10_first:1; /* Try READ_CAPACACITY_10 first */ 23162306a36Sopenharmony_ci unsigned security_supported:1; /* Supports Security Protocols */ 23262306a36Sopenharmony_ci unsigned is_visible:1; /* is the device visible in sysfs */ 23362306a36Sopenharmony_ci unsigned wce_default_on:1; /* Cache is ON by default */ 23462306a36Sopenharmony_ci unsigned no_dif:1; /* T10 PI (DIF) should be disabled */ 23562306a36Sopenharmony_ci unsigned broken_fua:1; /* Don't set FUA bit */ 23662306a36Sopenharmony_ci unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */ 23762306a36Sopenharmony_ci unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */ 23862306a36Sopenharmony_ci unsigned rpm_autosuspend:1; /* Enable runtime autosuspend at device 23962306a36Sopenharmony_ci * creation time */ 24062306a36Sopenharmony_ci unsigned ignore_media_change:1; /* Ignore MEDIA CHANGE on resume */ 24162306a36Sopenharmony_ci unsigned silence_suspend:1; /* Do not print runtime PM related messages */ 24262306a36Sopenharmony_ci unsigned no_vpd_size:1; /* No VPD size reported in header */ 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci unsigned cdl_supported:1; /* Command duration limits supported */ 24562306a36Sopenharmony_ci unsigned cdl_enable:1; /* Enable/disable Command duration limits */ 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci unsigned int queue_stopped; /* request queue is quiesced */ 24862306a36Sopenharmony_ci bool offline_already; /* Device offline message logged */ 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci atomic_t disk_events_disable_depth; /* disable depth for disk events */ 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ 25362306a36Sopenharmony_ci DECLARE_BITMAP(pending_events, SDEV_EVT_MAXBITS); /* pending events */ 25462306a36Sopenharmony_ci struct list_head event_list; /* asserted events */ 25562306a36Sopenharmony_ci struct work_struct event_work; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci unsigned int max_device_blocked; /* what device_blocked counts down from */ 25862306a36Sopenharmony_ci#define SCSI_DEFAULT_DEVICE_BLOCKED 3 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci atomic_t iorequest_cnt; 26162306a36Sopenharmony_ci atomic_t iodone_cnt; 26262306a36Sopenharmony_ci atomic_t ioerr_cnt; 26362306a36Sopenharmony_ci atomic_t iotmo_cnt; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci struct device sdev_gendev, 26662306a36Sopenharmony_ci sdev_dev; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci struct work_struct requeue_work; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci struct scsi_device_handler *handler; 27162306a36Sopenharmony_ci void *handler_data; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci size_t dma_drain_len; 27462306a36Sopenharmony_ci void *dma_drain_buf; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci unsigned int sg_timeout; 27762306a36Sopenharmony_ci unsigned int sg_reserved_size; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci struct bsg_device *bsg_dev; 28062306a36Sopenharmony_ci unsigned char access_state; 28162306a36Sopenharmony_ci struct mutex state_mutex; 28262306a36Sopenharmony_ci enum scsi_device_state sdev_state; 28362306a36Sopenharmony_ci struct task_struct *quiesced_by; 28462306a36Sopenharmony_ci unsigned long sdev_data[]; 28562306a36Sopenharmony_ci} __attribute__((aligned(sizeof(unsigned long)))); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci#define to_scsi_device(d) \ 28862306a36Sopenharmony_ci container_of(d, struct scsi_device, sdev_gendev) 28962306a36Sopenharmony_ci#define class_to_sdev(d) \ 29062306a36Sopenharmony_ci container_of(d, struct scsi_device, sdev_dev) 29162306a36Sopenharmony_ci#define transport_class_to_sdev(class_dev) \ 29262306a36Sopenharmony_ci to_scsi_device(class_dev->parent) 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci#define sdev_dbg(sdev, fmt, a...) \ 29562306a36Sopenharmony_ci dev_dbg(&(sdev)->sdev_gendev, fmt, ##a) 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci/* 29862306a36Sopenharmony_ci * like scmd_printk, but the device name is passed in 29962306a36Sopenharmony_ci * as a string pointer 30062306a36Sopenharmony_ci */ 30162306a36Sopenharmony_ci__printf(4, 5) void 30262306a36Sopenharmony_cisdev_prefix_printk(const char *, const struct scsi_device *, const char *, 30362306a36Sopenharmony_ci const char *, ...); 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci#define sdev_printk(l, sdev, fmt, a...) \ 30662306a36Sopenharmony_ci sdev_prefix_printk(l, sdev, NULL, fmt, ##a) 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci__printf(3, 4) void 30962306a36Sopenharmony_ciscmd_printk(const char *, const struct scsi_cmnd *, const char *, ...); 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci#define scmd_dbg(scmd, fmt, a...) \ 31262306a36Sopenharmony_ci do { \ 31362306a36Sopenharmony_ci struct request *__rq = scsi_cmd_to_rq((scmd)); \ 31462306a36Sopenharmony_ci \ 31562306a36Sopenharmony_ci if (__rq->q->disk) \ 31662306a36Sopenharmony_ci sdev_dbg((scmd)->device, "[%s] " fmt, \ 31762306a36Sopenharmony_ci __rq->q->disk->disk_name, ##a); \ 31862306a36Sopenharmony_ci else \ 31962306a36Sopenharmony_ci sdev_dbg((scmd)->device, fmt, ##a); \ 32062306a36Sopenharmony_ci } while (0) 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_cienum scsi_target_state { 32362306a36Sopenharmony_ci STARGET_CREATED = 1, 32462306a36Sopenharmony_ci STARGET_RUNNING, 32562306a36Sopenharmony_ci STARGET_REMOVE, 32662306a36Sopenharmony_ci STARGET_CREATED_REMOVE, 32762306a36Sopenharmony_ci STARGET_DEL, 32862306a36Sopenharmony_ci}; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci/* 33162306a36Sopenharmony_ci * scsi_target: representation of a scsi target, for now, this is only 33262306a36Sopenharmony_ci * used for single_lun devices. If no one has active IO to the target, 33362306a36Sopenharmony_ci * starget_sdev_user is NULL, else it points to the active sdev. 33462306a36Sopenharmony_ci */ 33562306a36Sopenharmony_cistruct scsi_target { 33662306a36Sopenharmony_ci struct scsi_device *starget_sdev_user; 33762306a36Sopenharmony_ci struct list_head siblings; 33862306a36Sopenharmony_ci struct list_head devices; 33962306a36Sopenharmony_ci struct device dev; 34062306a36Sopenharmony_ci struct kref reap_ref; /* last put renders target invisible */ 34162306a36Sopenharmony_ci unsigned int channel; 34262306a36Sopenharmony_ci unsigned int id; /* target id ... replace 34362306a36Sopenharmony_ci * scsi_device.id eventually */ 34462306a36Sopenharmony_ci unsigned int create:1; /* signal that it needs to be added */ 34562306a36Sopenharmony_ci unsigned int single_lun:1; /* Indicates we should only 34662306a36Sopenharmony_ci * allow I/O to one of the luns 34762306a36Sopenharmony_ci * for the device at a time. */ 34862306a36Sopenharmony_ci unsigned int pdt_1f_for_no_lun:1; /* PDT = 0x1f 34962306a36Sopenharmony_ci * means no lun present. */ 35062306a36Sopenharmony_ci unsigned int no_report_luns:1; /* Don't use 35162306a36Sopenharmony_ci * REPORT LUNS for scanning. */ 35262306a36Sopenharmony_ci unsigned int expecting_lun_change:1; /* A device has reported 35362306a36Sopenharmony_ci * a 3F/0E UA, other devices on 35462306a36Sopenharmony_ci * the same target will also. */ 35562306a36Sopenharmony_ci /* commands actually active on LLD. */ 35662306a36Sopenharmony_ci atomic_t target_busy; 35762306a36Sopenharmony_ci atomic_t target_blocked; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci /* 36062306a36Sopenharmony_ci * LLDs should set this in the slave_alloc host template callout. 36162306a36Sopenharmony_ci * If set to zero then there is not limit. 36262306a36Sopenharmony_ci */ 36362306a36Sopenharmony_ci unsigned int can_queue; 36462306a36Sopenharmony_ci unsigned int max_target_blocked; 36562306a36Sopenharmony_ci#define SCSI_DEFAULT_TARGET_BLOCKED 3 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci char scsi_level; 36862306a36Sopenharmony_ci enum scsi_target_state state; 36962306a36Sopenharmony_ci void *hostdata; /* available to low-level driver */ 37062306a36Sopenharmony_ci unsigned long starget_data[]; /* for the transport */ 37162306a36Sopenharmony_ci /* starget_data must be the last element!!!! */ 37262306a36Sopenharmony_ci} __attribute__((aligned(sizeof(unsigned long)))); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci#define to_scsi_target(d) container_of(d, struct scsi_target, dev) 37562306a36Sopenharmony_cistatic inline struct scsi_target *scsi_target(struct scsi_device *sdev) 37662306a36Sopenharmony_ci{ 37762306a36Sopenharmony_ci return to_scsi_target(sdev->sdev_gendev.parent); 37862306a36Sopenharmony_ci} 37962306a36Sopenharmony_ci#define transport_class_to_starget(class_dev) \ 38062306a36Sopenharmony_ci to_scsi_target(class_dev->parent) 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci#define starget_printk(prefix, starget, fmt, a...) \ 38362306a36Sopenharmony_ci dev_printk(prefix, &(starget)->dev, fmt, ##a) 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ciextern struct scsi_device *__scsi_add_device(struct Scsi_Host *, 38662306a36Sopenharmony_ci uint, uint, u64, void *hostdata); 38762306a36Sopenharmony_ciextern int scsi_add_device(struct Scsi_Host *host, uint channel, 38862306a36Sopenharmony_ci uint target, u64 lun); 38962306a36Sopenharmony_ciextern int scsi_register_device_handler(struct scsi_device_handler *scsi_dh); 39062306a36Sopenharmony_ciextern void scsi_remove_device(struct scsi_device *); 39162306a36Sopenharmony_ciextern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh); 39262306a36Sopenharmony_civoid scsi_attach_vpd(struct scsi_device *sdev); 39362306a36Sopenharmony_civoid scsi_cdl_check(struct scsi_device *sdev); 39462306a36Sopenharmony_ciint scsi_cdl_enable(struct scsi_device *sdev, bool enable); 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ciextern struct scsi_device *scsi_device_from_queue(struct request_queue *q); 39762306a36Sopenharmony_ciextern int __must_check scsi_device_get(struct scsi_device *); 39862306a36Sopenharmony_ciextern void scsi_device_put(struct scsi_device *); 39962306a36Sopenharmony_ciextern struct scsi_device *scsi_device_lookup(struct Scsi_Host *, 40062306a36Sopenharmony_ci uint, uint, u64); 40162306a36Sopenharmony_ciextern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *, 40262306a36Sopenharmony_ci uint, uint, u64); 40362306a36Sopenharmony_ciextern struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *, 40462306a36Sopenharmony_ci u64); 40562306a36Sopenharmony_ciextern struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *, 40662306a36Sopenharmony_ci u64); 40762306a36Sopenharmony_ciextern void starget_for_each_device(struct scsi_target *, void *, 40862306a36Sopenharmony_ci void (*fn)(struct scsi_device *, void *)); 40962306a36Sopenharmony_ciextern void __starget_for_each_device(struct scsi_target *, void *, 41062306a36Sopenharmony_ci void (*fn)(struct scsi_device *, 41162306a36Sopenharmony_ci void *)); 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci/* only exposed to implement shost_for_each_device */ 41462306a36Sopenharmony_ciextern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *, 41562306a36Sopenharmony_ci struct scsi_device *); 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci/** 41862306a36Sopenharmony_ci * shost_for_each_device - iterate over all devices of a host 41962306a36Sopenharmony_ci * @sdev: the &struct scsi_device to use as a cursor 42062306a36Sopenharmony_ci * @shost: the &struct scsi_host to iterate over 42162306a36Sopenharmony_ci * 42262306a36Sopenharmony_ci * Iterator that returns each device attached to @shost. This loop 42362306a36Sopenharmony_ci * takes a reference on each device and releases it at the end. If 42462306a36Sopenharmony_ci * you break out of the loop, you must call scsi_device_put(sdev). 42562306a36Sopenharmony_ci */ 42662306a36Sopenharmony_ci#define shost_for_each_device(sdev, shost) \ 42762306a36Sopenharmony_ci for ((sdev) = __scsi_iterate_devices((shost), NULL); \ 42862306a36Sopenharmony_ci (sdev); \ 42962306a36Sopenharmony_ci (sdev) = __scsi_iterate_devices((shost), (sdev))) 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci/** 43262306a36Sopenharmony_ci * __shost_for_each_device - iterate over all devices of a host (UNLOCKED) 43362306a36Sopenharmony_ci * @sdev: the &struct scsi_device to use as a cursor 43462306a36Sopenharmony_ci * @shost: the &struct scsi_host to iterate over 43562306a36Sopenharmony_ci * 43662306a36Sopenharmony_ci * Iterator that returns each device attached to @shost. It does _not_ 43762306a36Sopenharmony_ci * take a reference on the scsi_device, so the whole loop must be 43862306a36Sopenharmony_ci * protected by shost->host_lock. 43962306a36Sopenharmony_ci * 44062306a36Sopenharmony_ci * Note: The only reason to use this is because you need to access the 44162306a36Sopenharmony_ci * device list in interrupt context. Otherwise you really want to use 44262306a36Sopenharmony_ci * shost_for_each_device instead. 44362306a36Sopenharmony_ci */ 44462306a36Sopenharmony_ci#define __shost_for_each_device(sdev, shost) \ 44562306a36Sopenharmony_ci list_for_each_entry((sdev), &((shost)->__devices), siblings) 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ciextern int scsi_change_queue_depth(struct scsi_device *, int); 44862306a36Sopenharmony_ciextern int scsi_track_queue_full(struct scsi_device *, int); 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ciextern int scsi_set_medium_removal(struct scsi_device *, char); 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ciint scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, 45362306a36Sopenharmony_ci int subpage, unsigned char *buffer, int len, int timeout, 45462306a36Sopenharmony_ci int retries, struct scsi_mode_data *data, 45562306a36Sopenharmony_ci struct scsi_sense_hdr *); 45662306a36Sopenharmony_ciextern int scsi_mode_select(struct scsi_device *sdev, int pf, int sp, 45762306a36Sopenharmony_ci unsigned char *buffer, int len, int timeout, 45862306a36Sopenharmony_ci int retries, struct scsi_mode_data *data, 45962306a36Sopenharmony_ci struct scsi_sense_hdr *); 46062306a36Sopenharmony_ciextern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, 46162306a36Sopenharmony_ci int retries, struct scsi_sense_hdr *sshdr); 46262306a36Sopenharmony_ciextern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf, 46362306a36Sopenharmony_ci int buf_len); 46462306a36Sopenharmony_ciint scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, 46562306a36Sopenharmony_ci unsigned int len, unsigned char opcode, 46662306a36Sopenharmony_ci unsigned short sa); 46762306a36Sopenharmony_ciextern int scsi_device_set_state(struct scsi_device *sdev, 46862306a36Sopenharmony_ci enum scsi_device_state state); 46962306a36Sopenharmony_ciextern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, 47062306a36Sopenharmony_ci gfp_t gfpflags); 47162306a36Sopenharmony_ciextern void sdev_evt_send(struct scsi_device *sdev, struct scsi_event *evt); 47262306a36Sopenharmony_ciextern void sdev_evt_send_simple(struct scsi_device *sdev, 47362306a36Sopenharmony_ci enum scsi_device_event evt_type, gfp_t gfpflags); 47462306a36Sopenharmony_ciextern int scsi_device_quiesce(struct scsi_device *sdev); 47562306a36Sopenharmony_ciextern void scsi_device_resume(struct scsi_device *sdev); 47662306a36Sopenharmony_ciextern void scsi_target_quiesce(struct scsi_target *); 47762306a36Sopenharmony_ciextern void scsi_target_resume(struct scsi_target *); 47862306a36Sopenharmony_ciextern void scsi_scan_target(struct device *parent, unsigned int channel, 47962306a36Sopenharmony_ci unsigned int id, u64 lun, 48062306a36Sopenharmony_ci enum scsi_scan_mode rescan); 48162306a36Sopenharmony_ciextern void scsi_target_reap(struct scsi_target *); 48262306a36Sopenharmony_civoid scsi_block_targets(struct Scsi_Host *shost, struct device *dev); 48362306a36Sopenharmony_ciextern void scsi_target_unblock(struct device *, enum scsi_device_state); 48462306a36Sopenharmony_ciextern void scsi_remove_target(struct device *); 48562306a36Sopenharmony_ciextern const char *scsi_device_state_name(enum scsi_device_state); 48662306a36Sopenharmony_ciextern int scsi_is_sdev_device(const struct device *); 48762306a36Sopenharmony_ciextern int scsi_is_target_device(const struct device *); 48862306a36Sopenharmony_ciextern void scsi_sanitize_inquiry_string(unsigned char *s, int len); 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci/* Optional arguments to scsi_execute_cmd */ 49162306a36Sopenharmony_cistruct scsi_exec_args { 49262306a36Sopenharmony_ci unsigned char *sense; /* sense buffer */ 49362306a36Sopenharmony_ci unsigned int sense_len; /* sense buffer len */ 49462306a36Sopenharmony_ci struct scsi_sense_hdr *sshdr; /* decoded sense header */ 49562306a36Sopenharmony_ci blk_mq_req_flags_t req_flags; /* BLK_MQ_REQ flags */ 49662306a36Sopenharmony_ci int scmd_flags; /* SCMD flags */ 49762306a36Sopenharmony_ci int *resid; /* residual length */ 49862306a36Sopenharmony_ci}; 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ciint scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd, 50162306a36Sopenharmony_ci blk_opf_t opf, void *buffer, unsigned int bufflen, 50262306a36Sopenharmony_ci int timeout, int retries, 50362306a36Sopenharmony_ci const struct scsi_exec_args *args); 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ciextern void sdev_disable_disk_events(struct scsi_device *sdev); 50662306a36Sopenharmony_ciextern void sdev_enable_disk_events(struct scsi_device *sdev); 50762306a36Sopenharmony_ciextern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t); 50862306a36Sopenharmony_ciextern int scsi_vpd_tpg_id(struct scsi_device *, int *); 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci#ifdef CONFIG_PM 51162306a36Sopenharmony_ciextern int scsi_autopm_get_device(struct scsi_device *); 51262306a36Sopenharmony_ciextern void scsi_autopm_put_device(struct scsi_device *); 51362306a36Sopenharmony_ci#else 51462306a36Sopenharmony_cistatic inline int scsi_autopm_get_device(struct scsi_device *d) { return 0; } 51562306a36Sopenharmony_cistatic inline void scsi_autopm_put_device(struct scsi_device *d) {} 51662306a36Sopenharmony_ci#endif /* CONFIG_PM */ 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_cistatic inline int __must_check scsi_device_reprobe(struct scsi_device *sdev) 51962306a36Sopenharmony_ci{ 52062306a36Sopenharmony_ci return device_reprobe(&sdev->sdev_gendev); 52162306a36Sopenharmony_ci} 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_cistatic inline unsigned int sdev_channel(struct scsi_device *sdev) 52462306a36Sopenharmony_ci{ 52562306a36Sopenharmony_ci return sdev->channel; 52662306a36Sopenharmony_ci} 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_cistatic inline unsigned int sdev_id(struct scsi_device *sdev) 52962306a36Sopenharmony_ci{ 53062306a36Sopenharmony_ci return sdev->id; 53162306a36Sopenharmony_ci} 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci#define scmd_id(scmd) sdev_id((scmd)->device) 53462306a36Sopenharmony_ci#define scmd_channel(scmd) sdev_channel((scmd)->device) 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci/* 53762306a36Sopenharmony_ci * checks for positions of the SCSI state machine 53862306a36Sopenharmony_ci */ 53962306a36Sopenharmony_cistatic inline int scsi_device_online(struct scsi_device *sdev) 54062306a36Sopenharmony_ci{ 54162306a36Sopenharmony_ci return (sdev->sdev_state != SDEV_OFFLINE && 54262306a36Sopenharmony_ci sdev->sdev_state != SDEV_TRANSPORT_OFFLINE && 54362306a36Sopenharmony_ci sdev->sdev_state != SDEV_DEL); 54462306a36Sopenharmony_ci} 54562306a36Sopenharmony_cistatic inline int scsi_device_blocked(struct scsi_device *sdev) 54662306a36Sopenharmony_ci{ 54762306a36Sopenharmony_ci return sdev->sdev_state == SDEV_BLOCK || 54862306a36Sopenharmony_ci sdev->sdev_state == SDEV_CREATED_BLOCK; 54962306a36Sopenharmony_ci} 55062306a36Sopenharmony_cistatic inline int scsi_device_created(struct scsi_device *sdev) 55162306a36Sopenharmony_ci{ 55262306a36Sopenharmony_ci return sdev->sdev_state == SDEV_CREATED || 55362306a36Sopenharmony_ci sdev->sdev_state == SDEV_CREATED_BLOCK; 55462306a36Sopenharmony_ci} 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ciint scsi_internal_device_block_nowait(struct scsi_device *sdev); 55762306a36Sopenharmony_ciint scsi_internal_device_unblock_nowait(struct scsi_device *sdev, 55862306a36Sopenharmony_ci enum scsi_device_state new_state); 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_ci/* accessor functions for the SCSI parameters */ 56162306a36Sopenharmony_cistatic inline int scsi_device_sync(struct scsi_device *sdev) 56262306a36Sopenharmony_ci{ 56362306a36Sopenharmony_ci return sdev->sdtr; 56462306a36Sopenharmony_ci} 56562306a36Sopenharmony_cistatic inline int scsi_device_wide(struct scsi_device *sdev) 56662306a36Sopenharmony_ci{ 56762306a36Sopenharmony_ci return sdev->wdtr; 56862306a36Sopenharmony_ci} 56962306a36Sopenharmony_cistatic inline int scsi_device_dt(struct scsi_device *sdev) 57062306a36Sopenharmony_ci{ 57162306a36Sopenharmony_ci return sdev->ppr; 57262306a36Sopenharmony_ci} 57362306a36Sopenharmony_cistatic inline int scsi_device_dt_only(struct scsi_device *sdev) 57462306a36Sopenharmony_ci{ 57562306a36Sopenharmony_ci if (sdev->inquiry_len < 57) 57662306a36Sopenharmony_ci return 0; 57762306a36Sopenharmony_ci return (sdev->inquiry[56] & 0x0c) == 0x04; 57862306a36Sopenharmony_ci} 57962306a36Sopenharmony_cistatic inline int scsi_device_ius(struct scsi_device *sdev) 58062306a36Sopenharmony_ci{ 58162306a36Sopenharmony_ci if (sdev->inquiry_len < 57) 58262306a36Sopenharmony_ci return 0; 58362306a36Sopenharmony_ci return sdev->inquiry[56] & 0x01; 58462306a36Sopenharmony_ci} 58562306a36Sopenharmony_cistatic inline int scsi_device_qas(struct scsi_device *sdev) 58662306a36Sopenharmony_ci{ 58762306a36Sopenharmony_ci if (sdev->inquiry_len < 57) 58862306a36Sopenharmony_ci return 0; 58962306a36Sopenharmony_ci return sdev->inquiry[56] & 0x02; 59062306a36Sopenharmony_ci} 59162306a36Sopenharmony_cistatic inline int scsi_device_enclosure(struct scsi_device *sdev) 59262306a36Sopenharmony_ci{ 59362306a36Sopenharmony_ci return sdev->inquiry ? (sdev->inquiry[6] & (1<<6)) : 1; 59462306a36Sopenharmony_ci} 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_cistatic inline int scsi_device_protection(struct scsi_device *sdev) 59762306a36Sopenharmony_ci{ 59862306a36Sopenharmony_ci if (sdev->no_dif) 59962306a36Sopenharmony_ci return 0; 60062306a36Sopenharmony_ci 60162306a36Sopenharmony_ci return sdev->scsi_level > SCSI_2 && sdev->inquiry[5] & (1<<0); 60262306a36Sopenharmony_ci} 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_cistatic inline int scsi_device_tpgs(struct scsi_device *sdev) 60562306a36Sopenharmony_ci{ 60662306a36Sopenharmony_ci return sdev->inquiry ? (sdev->inquiry[5] >> 4) & 0x3 : 0; 60762306a36Sopenharmony_ci} 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci/** 61062306a36Sopenharmony_ci * scsi_device_supports_vpd - test if a device supports VPD pages 61162306a36Sopenharmony_ci * @sdev: the &struct scsi_device to test 61262306a36Sopenharmony_ci * 61362306a36Sopenharmony_ci * If the 'try_vpd_pages' flag is set it takes precedence. 61462306a36Sopenharmony_ci * Otherwise we will assume VPD pages are supported if the 61562306a36Sopenharmony_ci * SCSI level is at least SPC-3 and 'skip_vpd_pages' is not set. 61662306a36Sopenharmony_ci */ 61762306a36Sopenharmony_cistatic inline int scsi_device_supports_vpd(struct scsi_device *sdev) 61862306a36Sopenharmony_ci{ 61962306a36Sopenharmony_ci /* Attempt VPD inquiry if the device blacklist explicitly calls 62062306a36Sopenharmony_ci * for it. 62162306a36Sopenharmony_ci */ 62262306a36Sopenharmony_ci if (sdev->try_vpd_pages) 62362306a36Sopenharmony_ci return 1; 62462306a36Sopenharmony_ci /* 62562306a36Sopenharmony_ci * Although VPD inquiries can go to SCSI-2 type devices, 62662306a36Sopenharmony_ci * some USB ones crash on receiving them, and the pages 62762306a36Sopenharmony_ci * we currently ask for are mandatory for SPC-2 and beyond 62862306a36Sopenharmony_ci */ 62962306a36Sopenharmony_ci if (sdev->scsi_level >= SCSI_SPC_2 && !sdev->skip_vpd_pages) 63062306a36Sopenharmony_ci return 1; 63162306a36Sopenharmony_ci return 0; 63262306a36Sopenharmony_ci} 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_cistatic inline int scsi_device_busy(struct scsi_device *sdev) 63562306a36Sopenharmony_ci{ 63662306a36Sopenharmony_ci return sbitmap_weight(&sdev->budget_map); 63762306a36Sopenharmony_ci} 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_ci#define MODULE_ALIAS_SCSI_DEVICE(type) \ 64062306a36Sopenharmony_ci MODULE_ALIAS("scsi:t-" __stringify(type) "*") 64162306a36Sopenharmony_ci#define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x" 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci#endif /* _SCSI_SCSI_DEVICE_H */ 644