diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-08 21:19:19 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-08 21:19:19 -0800 |
commit | f3f62a38ceda4e4d34a1dc3ebbc0f8d426c9e8d9 (patch) | |
tree | 4f912f41c84017559376435c313987bdf8630b2c /include | |
parent | 140dfc9299c33bbfc9350fa061f5ab65cb83df13 (diff) | |
parent | 096cbc35eaecf5865a3274f21eae26955b32861b (diff) |
Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This patch is the usual mix of driver updates (srp, ipr, scsi_debug,
NCR5380, fnic, 53c974, ses, wd719x, hpsa, megaraid_sas).
Of those, wd7a9x is new and 53c974 is a rewrite of the old tmscsim
driver and the extensive work by Finn Thain rewrites all the NCR5380
based drivers.
There's also extensive infrastructure updates: a new logging
infrastructure for sense information and a rewrite of the tagged
command queue API and an assortment of minor updates"
* tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (183 commits)
scsi: set fmt to NULL scsi_extd_sense_format() by default
libsas: remove task_collector mode
wd719x: remove dma_cache_sync call
scsi_debug: add Report supported opcodes+tmfs; Compare and write
scsi_debug: change SCSI command parser to table driven
scsi_debug: add Capacity Changed Unit Attention
scsi_debug: append inject error flags onto scsi_cmnd object
scsi_debug: pinpoint invalid field in sense data
wd719x: Add firmware documentation
wd719x: Introduce Western Digital WD7193/7197/7296 PCI SCSI card driver
eeprom-93cx6: Add (read-only) support for 8-bit mode
esas2r: fix an oversight in setting return value
esas2r: fix an error path in esas2r_ioctl_handler
esas2r: fir error handling in do_fm_api
scsi: add SPC-3 command definitions
scsi: rename SERVICE_ACTION_IN to SERVICE_ACTION_IN_16
scsi: remove scsi_driver owner field
scsi: move scsi_dispatch_cmd to scsi_lib.c
scsi: stop passing a gfp_mask argument down the command setup path
scsi: remove scsi_next_command
...
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/blk-mq.h | 17 | ||||
-rw-r--r-- | include/linux/blkdev.h | 1 | ||||
-rw-r--r-- | include/linux/eeprom_93cx6.h | 4 | ||||
-rw-r--r-- | include/linux/libata.h | 4 | ||||
-rw-r--r-- | include/scsi/libfc.h | 2 | ||||
-rw-r--r-- | include/scsi/libiscsi.h | 2 | ||||
-rw-r--r-- | include/scsi/libsas.h | 17 | ||||
-rw-r--r-- | include/scsi/scsi.h | 12 | ||||
-rw-r--r-- | include/scsi/scsi_cmnd.h | 6 | ||||
-rw-r--r-- | include/scsi/scsi_dbg.h | 28 | ||||
-rw-r--r-- | include/scsi/scsi_device.h | 21 | ||||
-rw-r--r-- | include/scsi/scsi_driver.h | 1 | ||||
-rw-r--r-- | include/scsi/scsi_eh.h | 24 | ||||
-rw-r--r-- | include/scsi/scsi_host.h | 39 | ||||
-rw-r--r-- | include/scsi/scsi_ioctl.h | 4 | ||||
-rw-r--r-- | include/scsi/scsi_tcq.h | 87 | ||||
-rw-r--r-- | include/scsi/scsi_transport_spi.h | 1 | ||||
-rw-r--r-- | include/scsi/sg.h | 5 | ||||
-rw-r--r-- | include/trace/events/scsi.h | 2 | ||||
-rw-r--r-- | include/trace/events/target.h | 2 |
20 files changed, 115 insertions, 164 deletions
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index c9be1589415a..15f7034aa377 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -167,6 +167,23 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp, bool reserved); struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag); +enum { + BLK_MQ_UNIQUE_TAG_BITS = 16, + BLK_MQ_UNIQUE_TAG_MASK = (1 << BLK_MQ_UNIQUE_TAG_BITS) - 1, +}; + +u32 blk_mq_unique_tag(struct request *rq); + +static inline u16 blk_mq_unique_tag_to_hwq(u32 unique_tag) +{ + return unique_tag >> BLK_MQ_UNIQUE_TAG_BITS; +} + +static inline u16 blk_mq_unique_tag_to_tag(u32 unique_tag) +{ + return unique_tag & BLK_MQ_UNIQUE_TAG_MASK; +} + struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_index); struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *, unsigned int, int); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index aac0f9ea952a..6d76b8b4aa2b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1136,7 +1136,6 @@ static inline bool blk_needs_flush_plug(struct task_struct *tsk) /* * tag stuff */ -#define blk_rq_tagged(rq) ((rq)->cmd_flags & REQ_QUEUED) extern int blk_queue_start_tag(struct request_queue *, struct request *); extern struct request *blk_queue_find_tag(struct request_queue *, int); extern void blk_queue_end_tag(struct request_queue *, struct request *); diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h index e50f98b0297a..eb0b1988050a 100644 --- a/include/linux/eeprom_93cx6.h +++ b/include/linux/eeprom_93cx6.h @@ -75,6 +75,10 @@ extern void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word, u16 *data); extern void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word, __le16 *data, const u16 words); +extern void eeprom_93cx6_readb(struct eeprom_93cx6 *eeprom, + const u8 byte, u8 *data); +extern void eeprom_93cx6_multireadb(struct eeprom_93cx6 *eeprom, + const u8 byte, u8 *data, const u16 bytes); extern void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable); diff --git a/include/linux/libata.h b/include/linux/libata.h index bd5fefeaf548..bfbc817c34ee 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1191,9 +1191,9 @@ extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); extern int ata_scsi_slave_config(struct scsi_device *sdev); extern void ata_scsi_slave_destroy(struct scsi_device *sdev); extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, - int queue_depth, int reason); + int queue_depth); extern int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, - int queue_depth, int reason); + int queue_depth); extern struct ata_device *ata_dev_pair(struct ata_device *adev); extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap); diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index 52beadf9a29b..93d14daf0994 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -1105,8 +1105,6 @@ int fc_eh_abort(struct scsi_cmnd *); int fc_eh_device_reset(struct scsi_cmnd *); int fc_eh_host_reset(struct scsi_cmnd *); int fc_slave_alloc(struct scsi_device *); -int fc_change_queue_depth(struct scsi_device *, int qdepth, int reason); -int fc_change_queue_type(struct scsi_device *, int tag_type); /* * ELS/CT interface diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 728c9ad9feb0..4d1c46aac331 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -378,8 +378,6 @@ struct iscsi_host { /* * scsi host template */ -extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, - int reason); extern int iscsi_eh_abort(struct scsi_cmnd *sc); extern int iscsi_eh_recover_target(struct scsi_cmnd *sc); extern int iscsi_eh_session_reset(struct scsi_cmnd *sc); diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index ef7872c20da9..832dcc9f86ec 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -365,12 +365,6 @@ struct asd_sas_phy { struct scsi_core { struct Scsi_Host *shost; - struct mutex task_queue_flush; - spinlock_t task_queue_lock; - struct list_head task_queue; - int task_queue_size; - - struct task_struct *queue_thread; }; struct sas_ha_event { @@ -422,9 +416,6 @@ struct sas_ha_struct { struct asd_sas_port **sas_port; /* array of valid pointers, must be set */ int num_phys; /* must be set, gt 0, static */ - /* The class calls this to send a task for execution. */ - int lldd_max_execute_num; - int lldd_queue_size; int strict_wide_ports; /* both sas_addr and attached_sas_addr must match * their siblings when forming wide ports */ @@ -612,7 +603,6 @@ struct sas_ssp_task { struct sas_task { struct domain_device *dev; - struct list_head list; spinlock_t task_state_lock; unsigned task_state_flags; @@ -665,8 +655,7 @@ struct sas_domain_function_template { int (*lldd_dev_found)(struct domain_device *); void (*lldd_dev_gone)(struct domain_device *); - int (*lldd_execute_task)(struct sas_task *, int num, - gfp_t gfp_flags); + int (*lldd_execute_task)(struct sas_task *, gfp_t gfp_flags); /* Task Management Functions. Must be called from process context. */ int (*lldd_abort_task)(struct sas_task *); @@ -700,12 +689,10 @@ extern void sas_suspend_ha(struct sas_ha_struct *sas_ha); int sas_set_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates); int sas_phy_reset(struct sas_phy *phy, int hard_reset); -int sas_queue_up(struct sas_task *task); extern int sas_queuecommand(struct Scsi_Host * ,struct scsi_cmnd *); extern int sas_target_alloc(struct scsi_target *); extern int sas_slave_configure(struct scsi_device *); -extern int sas_change_queue_depth(struct scsi_device *, int new_depth, - int reason); +extern int sas_change_queue_depth(struct scsi_device *, int new_depth); extern int sas_change_queue_type(struct scsi_device *, int qt); extern int sas_bios_param(struct scsi_device *, struct block_device *, diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index d17178e6fcdd..8a7f8ad58aac 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -128,8 +128,10 @@ enum scsi_timeouts { #define MOVE_MEDIUM 0xa5 #define EXCHANGE_MEDIUM 0xa6 #define READ_12 0xa8 +#define SERVICE_ACTION_OUT_12 0xa9 #define WRITE_12 0xaa -#define READ_MEDIA_SERIAL_NUMBER 0xab +#define READ_MEDIA_SERIAL_NUMBER 0xab /* Obsolete with SPC-2 */ +#define SERVICE_ACTION_IN_12 0xab #define WRITE_VERIFY_12 0xae #define VERIFY_12 0xaf #define SEARCH_HIGH_12 0xb0 @@ -151,7 +153,9 @@ enum scsi_timeouts { #define VERIFY_16 0x8f #define SYNCHRONIZE_CACHE_16 0x91 #define WRITE_SAME_16 0x93 -#define SERVICE_ACTION_IN 0x9e +#define SERVICE_ACTION_BIDIRECTIONAL 0x9d +#define SERVICE_ACTION_IN_16 0x9e +#define SERVICE_ACTION_OUT_16 0x9f /* values for service action in */ #define SAI_READ_CAPACITY_16 0x10 #define SAI_GET_LBA_STATUS 0x12 @@ -165,8 +169,8 @@ enum scsi_timeouts { #define MI_REPORT_ALIASES 0x0b #define MI_REPORT_SUPPORTED_OPERATION_CODES 0x0c #define MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS 0x0d -#define MI_REPORT_PRIORITY 0x0e -#define MI_REPORT_TIMESTAMP 0x0f +#define MI_REPORT_PRIORITY 0x0e +#define MI_REPORT_TIMESTAMP 0x0f #define MI_MANAGEMENT_PROTOCOL_IN 0x10 /* value for MI_REPORT_TARGET_PGS ext header */ #define MI_EXT_HDR_PARAM_FMT 0x20 diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 522a5f27f553..9fc1aecfc813 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -53,6 +53,9 @@ struct scsi_pointer { volatile int phase; }; +/* for scmd->flags */ +#define SCMD_TAGGED (1 << 0) + struct scsi_cmnd { struct scsi_device *device; struct list_head list; /* scsi_cmnd participates in queue lists */ @@ -132,6 +135,7 @@ struct scsi_cmnd { * to be at an address < 16Mb). */ int result; /* Status code from lower level driver */ + int flags; /* Command flags */ unsigned char tag; /* SCSI-II queued command tag */ }; @@ -159,7 +163,7 @@ extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, size_t *offset, size_t *len); extern void scsi_kunmap_atomic_sg(void *virt); -extern int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask); +extern int scsi_init_io(struct scsi_cmnd *cmd); extern int scsi_dma_map(struct scsi_cmnd *cmd); extern void scsi_dma_unmap(struct scsi_cmnd *cmd); diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h index e89844cc2cd3..7982795df595 100644 --- a/include/scsi/scsi_dbg.h +++ b/include/scsi/scsi_dbg.h @@ -2,23 +2,27 @@ #define _SCSI_SCSI_DBG_H struct scsi_cmnd; +struct scsi_device; struct scsi_sense_hdr; extern void scsi_print_command(struct scsi_cmnd *); -extern void __scsi_print_command(unsigned char *); -extern void scsi_show_extd_sense(unsigned char, unsigned char); -extern void scsi_show_sense_hdr(struct scsi_sense_hdr *); -extern void scsi_print_sense_hdr(const char *, struct scsi_sense_hdr *); -extern void scsi_cmd_print_sense_hdr(struct scsi_cmnd *, const char *, - struct scsi_sense_hdr *); -extern void scsi_print_sense(char *, struct scsi_cmnd *); -extern void __scsi_print_sense(const char *name, +extern void __scsi_print_command(const unsigned char *, size_t); +extern void scsi_show_extd_sense(const struct scsi_device *, const char *, + unsigned char, unsigned char); +extern void scsi_show_sense_hdr(const struct scsi_device *, const char *, + const struct scsi_sense_hdr *); +extern void scsi_print_sense_hdr(const struct scsi_device *, const char *, + const struct scsi_sense_hdr *); +extern void scsi_print_sense(const struct scsi_cmnd *); +extern void __scsi_print_sense(const struct scsi_device *, const char *name, const unsigned char *sense_buffer, int sense_len); -extern void scsi_show_result(int); -extern void scsi_print_result(struct scsi_cmnd *); -extern void scsi_print_status(unsigned char); +extern void scsi_print_result(struct scsi_cmnd *, const char *, int); +extern const char *scsi_hostbyte_string(int); +extern const char *scsi_driverbyte_string(int); +extern const char *scsi_mlreturn_string(int); extern const char *scsi_sense_key_string(unsigned char); -extern const char *scsi_extd_sense_format(unsigned char, unsigned char); +extern const char *scsi_extd_sense_format(unsigned char, unsigned char, + const char **); #endif /* _SCSI_SCSI_DBG_H */ diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 27ecee73bd72..6364e23454dd 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -141,7 +141,6 @@ struct scsi_device { unsigned ppr:1; /* Device supports PPR messages */ unsigned tagged_supported:1; /* Supports SCSI-II tagged queuing */ unsigned simple_tags:1; /* simple queue tag messages are enabled */ - unsigned ordered_tags:1;/* ordered queue tag messages are enabled */ unsigned was_reset:1; /* There was a bus reset on the bus for * this device */ unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN @@ -201,11 +200,6 @@ struct scsi_device { unsigned long sdev_data[0]; } __attribute__((aligned(sizeof(unsigned long)))); -struct scsi_dh_devlist { - char *vendor; - char *model; -}; - typedef void (*activate_complete)(void *, int); struct scsi_device_handler { /* Used by the infrastructure */ @@ -214,9 +208,8 @@ struct scsi_device_handler { /* Filled by the hardware handler */ struct module *module; const char *name; - const struct scsi_dh_devlist *devlist; int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); - int (*attach)(struct scsi_device *); + struct scsi_dh_data *(*attach)(struct scsi_device *); void (*detach)(struct scsi_device *); int (*activate)(struct scsi_device *, activate_complete, void *); int (*prep_fn)(struct scsi_device *, struct request *); @@ -228,7 +221,6 @@ struct scsi_dh_data { struct scsi_device_handler *scsi_dh; struct scsi_device *sdev; struct kref kref; - char buf[0]; }; #define to_scsi_device(d) \ @@ -244,6 +236,15 @@ struct scsi_dh_data { #define sdev_dbg(sdev, fmt, a...) \ dev_dbg(&(sdev)->sdev_gendev, fmt, ##a) +/* + * like scmd_printk, but the device name is passed in + * as a string pointer + */ +#define sdev_prefix_printk(l, sdev, p, fmt, a...) \ + (p) ? \ + sdev_printk(l, sdev, "[%s] " fmt, p, ##a) : \ + sdev_printk(l, sdev, fmt, ##a) + #define scmd_printk(prefix, scmd, fmt, a...) \ (scmd)->request->rq_disk ? \ sdev_printk(prefix, (scmd)->device, "[%s] " fmt, \ @@ -379,7 +380,7 @@ extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *, #define __shost_for_each_device(sdev, shost) \ list_for_each_entry((sdev), &((shost)->__devices), siblings) -extern void scsi_adjust_queue_depth(struct scsi_device *, int, int); +extern int scsi_change_queue_depth(struct scsi_device *, int); extern int scsi_track_queue_full(struct scsi_device *, int); extern int scsi_set_medium_removal(struct scsi_device *, char); diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index c2b759809d8a..891a658aa867 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h @@ -9,7 +9,6 @@ struct scsi_cmnd; struct scsi_device; struct scsi_driver { - struct module *owner; struct device_driver gendrv; void (*rescan)(struct device *); diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index 06a8790893ef..1e1421b06565 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h @@ -27,10 +27,10 @@ struct scsi_sense_hdr { /* See SPC-3 section 4.5 */ u8 additional_length; /* always 0 for fixed sense format */ }; -static inline int scsi_sense_valid(struct scsi_sense_hdr *sshdr) +static inline bool scsi_sense_valid(const struct scsi_sense_hdr *sshdr) { if (!sshdr) - return 0; + return false; return (sshdr->response_code & 0x70) == 0x70; } @@ -42,12 +42,12 @@ extern void scsi_eh_flush_done_q(struct list_head *done_q); extern void scsi_report_bus_reset(struct Scsi_Host *, int); extern void scsi_report_device_reset(struct Scsi_Host *, int, int); extern int scsi_block_when_processing_errors(struct scsi_device *); -extern int scsi_normalize_sense(const u8 *sense_buffer, int sb_len, - struct scsi_sense_hdr *sshdr); -extern int scsi_command_normalize_sense(struct scsi_cmnd *cmd, - struct scsi_sense_hdr *sshdr); +extern bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, + struct scsi_sense_hdr *sshdr); +extern bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd, + struct scsi_sense_hdr *sshdr); -static inline int scsi_sense_is_deferred(struct scsi_sense_hdr *sshdr) +static inline bool scsi_sense_is_deferred(const struct scsi_sense_hdr *sshdr) { return ((sshdr->response_code >= 0x70) && (sshdr->response_code & 1)); } @@ -60,15 +60,7 @@ extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq); -/* - * Reset request from external source - */ -#define SCSI_TRY_RESET_DEVICE 1 -#define SCSI_TRY_RESET_BUS 2 -#define SCSI_TRY_RESET_HOST 3 -#define SCSI_TRY_RESET_TARGET 4 - -extern int scsi_reset_provider(struct scsi_device *, int); +extern int scsi_ioctl_reset(struct scsi_device *, int __user *); struct scsi_eh_save { /* saved state */ diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 5e362489ee88..c8a462ef9a4e 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -46,12 +46,6 @@ struct blk_queue_tags; #define DISABLE_CLUSTERING 0 #define ENABLE_CLUSTERING 1 -enum { - SCSI_QDEPTH_DEFAULT, /* default requested change, e.g. from sysfs */ - SCSI_QDEPTH_QFULL, /* scsi-ml requested due to queue full */ - SCSI_QDEPTH_RAMP_UP, /* scsi-ml requested due to threshold event */ -}; - struct scsi_host_template { struct module *module; const char *name; @@ -195,7 +189,7 @@ struct scsi_host_template { * Things currently recommended to be handled at this time include: * * 1. Setting the device queue depth. Proper setting of this is - * described in the comments for scsi_adjust_queue_depth. + * described in the comments for scsi_change_queue_depth. * 2. Determining if the device supports the various synchronous * negotiation protocols. The device struct will already have * responded to INQUIRY and the results of the standard items @@ -281,7 +275,7 @@ struct scsi_host_template { * * Status: OPTIONAL */ - int (* change_queue_depth)(struct scsi_device *, int, int); + int (* change_queue_depth)(struct scsi_device *, int); /* * Fill in this function to allow the changing of tag types @@ -422,6 +416,16 @@ struct scsi_host_template { unsigned char present; /* + * Let the block layer assigns tags to all commands. + */ + unsigned use_blk_tags:1; + + /* + * Track QUEUE_FULL events and reduce queue depth on demand. + */ + unsigned track_queue_depth:1; + + /* * This specifies the mode that a LLD supports. */ unsigned supported_mode:2; @@ -451,11 +455,6 @@ struct scsi_host_template { */ unsigned skip_settle_delay:1; - /* - * True if we are using ordered write support. - */ - unsigned ordered_tag:1; - /* True if the controller does not support WRITE SAME */ unsigned no_write_same:1; @@ -638,6 +637,14 @@ struct Scsi_Host { short unsigned int sg_prot_tablesize; unsigned int max_sectors; unsigned long dma_boundary; + /* + * In scsi-mq mode, the number of hardware queues supported by the LLD. + * + * Note: it is assumed that each hardware queue has a queue depth of + * can_queue. In other words, the total queue depth per host + * is nr_hw_queues * can_queue. + */ + unsigned nr_hw_queues; /* * Used to assign serial numbers to the cmds. * Protected by the host lock. @@ -647,7 +654,6 @@ struct Scsi_Host { unsigned active_mode:2; unsigned unchecked_isa_dma:1; unsigned use_clustering:1; - unsigned use_blk_tcq:1; /* * Host has requested that no further requests come through for the @@ -662,11 +668,6 @@ struct Scsi_Host { */ unsigned reverse_ordering:1; - /* - * Ordered write support - */ - unsigned ordered_tag:1; - /* Task mgmt function in progress */ unsigned tmf_in_progress:1; diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h index b9006848b813..8d19d1d233c3 100644 --- a/include/scsi/scsi_ioctl.h +++ b/include/scsi/scsi_ioctl.h @@ -40,9 +40,9 @@ typedef struct scsi_fctargaddress { unsigned char host_wwn[8]; // include NULL term. } Scsi_FCTargAddress; +int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, + int cmd, bool ndelay); extern int scsi_ioctl(struct scsi_device *, int, void __user *); -extern int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd, - void __user *arg, int ndelay); #endif /* __KERNEL__ */ #endif /* _SCSI_IOCTL_H */ diff --git a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h index 56ed843969ca..fe4a70299419 100644 --- a/include/scsi/scsi_tcq.h +++ b/include/scsi/scsi_tcq.h @@ -16,20 +16,16 @@ #ifdef CONFIG_BLOCK +int scsi_change_queue_type(struct scsi_device *sdev, int tag_type); + /** * scsi_get_tag_type - get the type of tag the device supports * @sdev: the scsi device - * - * Notes: - * If the drive only supports simple tags, returns MSG_SIMPLE_TAG - * if it supports all tag types, returns MSG_ORDERED_TAG. */ static inline int scsi_get_tag_type(struct scsi_device *sdev) { if (!sdev->tagged_supported) return 0; - if (sdev->ordered_tags) - return MSG_ORDERED_TAG; if (sdev->simple_tags) return MSG_SIMPLE_TAG; return 0; @@ -39,90 +35,33 @@ static inline void scsi_set_tag_type(struct scsi_device *sdev, int tag) { switch (tag) { case MSG_ORDERED_TAG: - sdev->ordered_tags = 1; - /* fall through */ case MSG_SIMPLE_TAG: sdev->simple_tags = 1; break; case 0: /* fall through */ default: - sdev->ordered_tags = 0; sdev->simple_tags = 0; break; } } -/** - * scsi_activate_tcq - turn on tag command queueing - * @SDpnt: device to turn on TCQ for - * @depth: queue depth - * - * Notes: - * Eventually, I hope depth would be the maximum depth - * the device could cope with and the real queue depth - * would be adjustable from 0 to depth. - **/ -static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth) -{ - if (!sdev->tagged_supported) - return; - - if (shost_use_blk_mq(sdev->host)) - queue_flag_set_unlocked(QUEUE_FLAG_QUEUED, sdev->request_queue); - else if (!blk_queue_tagged(sdev->request_queue)) - blk_queue_init_tags(sdev->request_queue, depth, - sdev->host->bqt); - - scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); -} - -/** - * scsi_deactivate_tcq - turn off tag command queueing - * @SDpnt: device to turn off TCQ for - **/ -static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth) -{ - if (blk_queue_tagged(sdev->request_queue)) - blk_queue_free_tags(sdev->request_queue); - scsi_adjust_queue_depth(sdev, 0, depth); -} - -/** - * scsi_populate_tag_msg - place a tag message in a buffer - * @SCpnt: pointer to the Scsi_Cmnd for the tag - * @msg: pointer to the area to place the tag - * - * Notes: - * designed to create the correct type of tag message for the - * particular request. Returns the size of the tag message. - * May return 0 if TCQ is disabled for this device. - **/ -static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg) -{ - struct request *req = cmd->request; - - if (blk_rq_tagged(req)) { - *msg++ = MSG_SIMPLE_TAG; - *msg++ = req->tag; - return 2; - } - - return 0; -} static inline struct scsi_cmnd *scsi_mq_find_tag(struct Scsi_Host *shost, - unsigned int hw_ctx, int tag) + int unique_tag) { - struct request *req; + u16 hwq = blk_mq_unique_tag_to_hwq(unique_tag); + struct request *req = NULL; - req = blk_mq_tag_to_rq(shost->tag_set.tags[hw_ctx], tag); + if (hwq < shost->tag_set.nr_hw_queues) + req = blk_mq_tag_to_rq(shost->tag_set.tags[hwq], + blk_mq_unique_tag_to_tag(unique_tag)); return req ? (struct scsi_cmnd *)req->special : NULL; } /** * scsi_find_tag - find a tagged command by device * @SDpnt: pointer to the ScSI device - * @tag: the tag number + * @tag: tag generated by blk_mq_unique_tag() * * Notes: * Only works with tags allocated by the generic blk layer. @@ -133,9 +72,9 @@ static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag) if (tag != SCSI_NO_TAG) { if (shost_use_blk_mq(sdev->host)) - return scsi_mq_find_tag(sdev->host, 0, tag); + return scsi_mq_find_tag(sdev->host, tag); - req = blk_queue_find_tag(sdev->request_queue, tag); + req = blk_queue_find_tag(sdev->request_queue, tag); return req ? (struct scsi_cmnd *)req->special : NULL; } @@ -174,7 +113,7 @@ static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth) /** * scsi_host_find_tag - find the tagged command by host * @shost: pointer to scsi_host - * @tag: tag of the scsi_cmnd + * @tag: tag generated by blk_mq_unique_tag() * * Notes: * Only works with tags allocated by the generic blk layer. @@ -186,7 +125,7 @@ static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost, if (tag != SCSI_NO_TAG) { if (shost_use_blk_mq(shost)) - return scsi_mq_find_tag(shost, 0, tag); + return scsi_mq_find_tag(shost, tag); req = blk_map_queue_find_tag(shost->bqt, tag); return req ? (struct scsi_cmnd *)req->special : NULL; } diff --git a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h index 7497a383b1a4..a4fa52b4d5c5 100644 --- a/include/scsi/scsi_transport_spi.h +++ b/include/scsi/scsi_transport_spi.h @@ -157,5 +157,6 @@ int spi_populate_width_msg(unsigned char *msg, int width); int spi_populate_sync_msg(unsigned char *msg, int period, int offset); int spi_populate_ppr_msg(unsigned char *msg, int period, int offset, int width, int options); +int spi_populate_tag_msg(unsigned char *msg, struct scsi_cmnd *cmd); #endif /* SCSI_TRANSPORT_SPI_H */ diff --git a/include/scsi/sg.h b/include/scsi/sg.h index 750e5db7c6bf..3afec7032448 100644 --- a/include/scsi/sg.h +++ b/include/scsi/sg.h @@ -164,12 +164,15 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ /* Returns -EBUSY if occupied. 3rd argument pointer to int (see next) */ #define SG_SCSI_RESET 0x2284 -/* Associated values that can be given to SG_SCSI_RESET follow */ +/* Associated values that can be given to SG_SCSI_RESET follow. + * SG_SCSI_RESET_NO_ESCALATE may be OR-ed to the _DEVICE, _TARGET, _BUS + * or _HOST reset value so only that action is attempted. */ #define SG_SCSI_RESET_NOTHING 0 #define SG_SCSI_RESET_DEVICE 1 #define SG_SCSI_RESET_BUS 2 #define SG_SCSI_RESET_HOST 3 #define SG_SCSI_RESET_TARGET 4 +#define SG_SCSI_RESET_NO_ESCALATE 0x100 /* synchronous SCSI command ioctl, (only in version 3 interface) */ #define SG_IO 0x2285 /* similar effect as write() followed by read() */ diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h index db6c93510f74..079bd10a01b4 100644 --- a/include/trace/events/scsi.h +++ b/include/trace/events/scsi.h @@ -94,7 +94,7 @@ scsi_opcode_name(WRITE_16), \ scsi_opcode_name(VERIFY_16), \ scsi_opcode_name(WRITE_SAME_16), \ - scsi_opcode_name(SERVICE_ACTION_IN), \ + scsi_opcode_name(SERVICE_ACTION_IN_16), \ scsi_opcode_name(SAI_READ_CAPACITY_16), \ scsi_opcode_name(SAI_GET_LBA_STATUS), \ scsi_opcode_name(MI_REPORT_TARGET_PGS), \ diff --git a/include/trace/events/target.h b/include/trace/events/target.h index da9cc0f05c93..45403443dd82 100644 --- a/include/trace/events/target.h +++ b/include/trace/events/target.h @@ -96,7 +96,7 @@ scsi_opcode_name(WRITE_16), \ scsi_opcode_name(VERIFY_16), \ scsi_opcode_name(WRITE_SAME_16), \ - scsi_opcode_name(SERVICE_ACTION_IN), \ + scsi_opcode_name(SERVICE_ACTION_IN_16), \ scsi_opcode_name(SAI_READ_CAPACITY_16), \ scsi_opcode_name(SAI_GET_LBA_STATUS), \ scsi_opcode_name(MI_REPORT_TARGET_PGS), \ |