diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/moduleparam.h | 5 | ||||
-rw-r--r-- | include/linux/scatterlist.h | 6 | ||||
-rw-r--r-- | include/scsi/libsrp.h | 78 | ||||
-rw-r--r-- | include/scsi/scsi.h | 3 | ||||
-rw-r--r-- | include/scsi/scsi_cmnd.h | 3 | ||||
-rw-r--r-- | include/scsi/scsi_device.h | 39 | ||||
-rw-r--r-- | include/scsi/scsi_devinfo.h | 5 | ||||
-rw-r--r-- | include/scsi/scsi_driver.h | 3 | ||||
-rw-r--r-- | include/scsi/scsi_host.h | 68 | ||||
-rw-r--r-- | include/scsi/scsi_tcq.h | 28 | ||||
-rw-r--r-- | include/scsi/scsi_tgt.h | 21 | ||||
-rw-r--r-- | include/scsi/scsi_tgt_if.h | 108 | ||||
-rw-r--r-- | include/scsi/scsi_transport.h | 2 | ||||
-rw-r--r-- | include/scsi/scsi_transport_fc.h | 4 | ||||
-rw-r--r-- | include/scsi/sg.h | 92 |
15 files changed, 116 insertions, 349 deletions
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index b1990c5524e1..494f99e852da 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -381,6 +381,11 @@ extern int param_set_ulong(const char *val, const struct kernel_param *kp); extern int param_get_ulong(char *buffer, const struct kernel_param *kp); #define param_check_ulong(name, p) __param_check(name, p, unsigned long) +extern struct kernel_param_ops param_ops_ullong; +extern int param_set_ullong(const char *val, const struct kernel_param *kp); +extern int param_get_ullong(char *buffer, const struct kernel_param *kp); +#define param_check_ullong(name, p) __param_check(name, p, unsigned long long) + extern struct kernel_param_ops param_ops_charp; extern int param_set_charp(const char *val, const struct kernel_param *kp); extern int param_get_charp(char *buffer, const struct kernel_param *kp); diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index a964f7285600..f4ec8bbcb372 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -229,10 +229,10 @@ void sg_init_one(struct scatterlist *, const void *, unsigned int); typedef struct scatterlist *(sg_alloc_fn)(unsigned int, gfp_t); typedef void (sg_free_fn)(struct scatterlist *, unsigned int); -void __sg_free_table(struct sg_table *, unsigned int, sg_free_fn *); +void __sg_free_table(struct sg_table *, unsigned int, bool, sg_free_fn *); void sg_free_table(struct sg_table *); -int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, gfp_t, - sg_alloc_fn *); +int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, + struct scatterlist *, gfp_t, sg_alloc_fn *); int sg_alloc_table(struct sg_table *, unsigned int, gfp_t); int sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages, unsigned int n_pages, diff --git a/include/scsi/libsrp.h b/include/scsi/libsrp.h deleted file mode 100644 index f4105c91af53..000000000000 --- a/include/scsi/libsrp.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef __LIBSRP_H__ -#define __LIBSRP_H__ - -#include <linux/list.h> -#include <linux/kfifo.h> -#include <scsi/scsi_cmnd.h> -#include <scsi/scsi_host.h> -#include <scsi/srp.h> - -enum iue_flags { - V_DIOVER, - V_WRITE, - V_LINKED, - V_FLYING, -}; - -struct srp_buf { - dma_addr_t dma; - void *buf; -}; - -struct srp_queue { - void *pool; - void *items; - struct kfifo queue; - spinlock_t lock; -}; - -struct srp_target { - struct Scsi_Host *shost; - struct device *dev; - - spinlock_t lock; - struct list_head cmd_queue; - - size_t srp_iu_size; - struct srp_queue iu_queue; - size_t rx_ring_size; - struct srp_buf **rx_ring; - - void *ldata; -}; - -struct iu_entry { - struct srp_target *target; - - struct list_head ilist; - dma_addr_t remote_token; - unsigned long flags; - - struct srp_buf *sbuf; -}; - -typedef int (srp_rdma_t)(struct scsi_cmnd *, struct scatterlist *, int, - struct srp_direct_buf *, int, - enum dma_data_direction, unsigned int); -extern int srp_target_alloc(struct srp_target *, struct device *, size_t, size_t); -extern void srp_target_free(struct srp_target *); - -extern struct iu_entry *srp_iu_get(struct srp_target *); -extern void srp_iu_put(struct iu_entry *); - -extern int srp_cmd_queue(struct Scsi_Host *, struct srp_cmd *, void *, u64, u64); -extern int srp_transfer_data(struct scsi_cmnd *, struct srp_cmd *, - srp_rdma_t, int, int); - - -static inline struct srp_target *host_to_srp_target(struct Scsi_Host *host) -{ - return (struct srp_target *) host->hostdata; -} - -static inline int srp_cmd_direction(struct srp_cmd *cmd) -{ - return (cmd->buf_fmt >> 4) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; -} - -#endif diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 0a4edfe8af51..e6df23cae7be 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -332,6 +332,7 @@ static inline int scsi_status_is_good(int status) #define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ #define TYPE_RBC 0x0e #define TYPE_OSD 0x11 +#define TYPE_ZBC 0x14 #define TYPE_NO_LUN 0x7f /* SCSI protocols; these are taken from SPC-3 section 7.5 */ @@ -385,7 +386,7 @@ struct scsi_lun { #define SCSI_W_LUN_ACCESS_CONTROL (SCSI_W_LUN_BASE + 2) #define SCSI_W_LUN_TARGET_LOG_PAGE (SCSI_W_LUN_BASE + 3) -static inline int scsi_is_wlun(unsigned int lun) +static inline int scsi_is_wlun(u64 lun) { return (lun & 0xff00) == SCSI_W_LUN_BASE; } diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index e0ae71098144..73f349044941 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -150,9 +150,7 @@ static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) } extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); -extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t); extern void scsi_put_command(struct scsi_cmnd *); -extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *); extern void scsi_finish_command(struct scsi_cmnd *cmd); extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, @@ -160,7 +158,6 @@ extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, extern void scsi_kunmap_atomic_sg(void *virt); extern int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask); -extern void scsi_release_buffers(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_device.h b/include/scsi/scsi_device.h index 27ab31017f09..1a0d1842962e 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -81,9 +81,9 @@ struct scsi_device { struct list_head siblings; /* list of all devices on this host */ struct list_head same_target_siblings; /* just the devices sharing same target id */ - /* this is now protected by the request_queue->queue_lock */ - unsigned int device_busy; /* commands actually active on - * low-level. protected by queue_lock. */ + atomic_t device_busy; /* commands actually active on LLDD */ + atomic_t device_blocked; /* Device returned QUEUE_FULL. */ + spinlock_t list_lock; struct list_head cmd_list; /* queue of in use SCSI Command structures */ struct list_head starved_entry; @@ -98,8 +98,8 @@ struct scsi_device { unsigned long last_queue_ramp_up; /* last queue ramp up time */ - unsigned int id, lun, channel; - + unsigned int id, channel; + u64 lun; unsigned int manufacturer; /* Manufacturer of device, for using * vendor-specific cmd's */ unsigned sector_size; /* size in bytes */ @@ -127,7 +127,6 @@ struct scsi_device { * pass settings from slave_alloc to scsi * core. */ unsigned int eh_timeout; /* Error handling timeout */ - unsigned writeable:1; unsigned removable:1; unsigned changed:1; /* Data invalid due to media change */ unsigned busy:1; /* Used to prevent races */ @@ -155,6 +154,7 @@ struct scsi_device { unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ unsigned skip_vpd_pages:1; /* do not read VPD pages */ + unsigned try_vpd_pages:1; /* attempt to read VPD pages */ unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ unsigned no_start_on_add:1; /* do not issue start on add */ unsigned allow_restart:1; /* issue START_UNIT in error handler */ @@ -182,8 +182,6 @@ struct scsi_device { struct list_head event_list; /* asserted events */ struct work_struct event_work; - unsigned int device_blocked; /* Device returned QUEUE_FULL. */ - unsigned int max_device_blocked; /* what device_blocked counts down from */ #define SCSI_DEFAULT_DEVICE_BLOCKED 3 @@ -291,14 +289,15 @@ struct scsi_target { unsigned int expecting_lun_change:1; /* A device has reported * a 3F/0E UA, other devices on * the same target will also. */ - /* commands actually active on LLD. protected by host lock. */ - unsigned int target_busy; + /* commands actually active on LLD. */ + atomic_t target_busy; + atomic_t target_blocked; + /* * LLDs should set this in the slave_alloc host template callout. * If set to zero then there is not limit. */ unsigned int can_queue; - unsigned int target_blocked; unsigned int max_target_blocked; #define SCSI_DEFAULT_TARGET_BLOCKED 3 @@ -321,9 +320,9 @@ static inline struct scsi_target *scsi_target(struct scsi_device *sdev) dev_printk(prefix, &(starget)->dev, fmt, ##a) extern struct scsi_device *__scsi_add_device(struct Scsi_Host *, - uint, uint, uint, void *hostdata); + uint, uint, u64, void *hostdata); extern int scsi_add_device(struct Scsi_Host *host, uint channel, - uint target, uint lun); + uint target, u64 lun); extern int scsi_register_device_handler(struct scsi_device_handler *scsi_dh); extern void scsi_remove_device(struct scsi_device *); extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh); @@ -332,13 +331,13 @@ void scsi_attach_vpd(struct scsi_device *sdev); extern int scsi_device_get(struct scsi_device *); extern void scsi_device_put(struct scsi_device *); extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *, - uint, uint, uint); + uint, uint, u64); extern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *, - uint, uint, uint); + uint, uint, u64); extern struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *, - uint); + u64); extern struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *, - uint); + u64); extern void starget_for_each_device(struct scsi_target *, void *, void (*fn)(struct scsi_device *, void *)); extern void __starget_for_each_device(struct scsi_target *, void *, @@ -411,13 +410,13 @@ extern void scsi_device_resume(struct scsi_device *sdev); extern void scsi_target_quiesce(struct scsi_target *); extern void scsi_target_resume(struct scsi_target *); extern void scsi_scan_target(struct device *parent, unsigned int channel, - unsigned int id, unsigned int lun, int rescan); + unsigned int id, u64 lun, int rescan); extern void scsi_target_reap(struct scsi_target *); extern void scsi_target_block(struct device *); extern void scsi_target_unblock(struct device *, enum scsi_device_state); extern void scsi_remove_target(struct device *); -extern void int_to_scsilun(unsigned int, struct scsi_lun *); -extern int scsilun_to_int(struct scsi_lun *); +extern void int_to_scsilun(u64, struct scsi_lun *); +extern u64 scsilun_to_int(struct scsi_lun *); extern const char *scsi_device_state_name(enum scsi_device_state); extern int scsi_is_sdev_device(const struct device *); extern int scsi_is_target_device(const struct device *); diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h index 447d2d7466fc..183eaab7c380 100644 --- a/include/scsi/scsi_devinfo.h +++ b/include/scsi/scsi_devinfo.h @@ -32,4 +32,9 @@ #define BLIST_ATTACH_PQ3 0x1000000 /* Scan: Attach to PQ3 devices */ #define BLIST_NO_DIF 0x2000000 /* Disable T10 PI (DIF) */ #define BLIST_SKIP_VPD_PAGES 0x4000000 /* Ignore SBC-3 VPD pages */ +#define BLIST_SCSI3LUN 0x8000000 /* Scan more than 256 LUNs + for sequential scan */ +#define BLIST_TRY_VPD_PAGES 0x10000000 /* Attempt to read VPD pages */ +#define BLIST_NO_RSOC 0x20000000 /* don't try to issue RSOC */ + #endif diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index 36c4114ed9bc..c2b759809d8a 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h @@ -29,7 +29,4 @@ extern int scsi_register_interface(struct class_interface *); #define scsi_unregister_interface(intf) \ class_interface_unregister(intf) -int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req); -int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); - #endif /* _SCSI_SCSI_DRIVER_H */ diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 94844fc77b97..ba2034779961 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -7,6 +7,7 @@ #include <linux/workqueue.h> #include <linux/mutex.h> #include <linux/seq_file.h> +#include <linux/blk-mq.h> #include <scsi/scsi.h> struct request_queue; @@ -132,27 +133,6 @@ struct scsi_host_template { int (* queuecommand)(struct Scsi_Host *, struct scsi_cmnd *); /* - * The transfer functions are used to queue a scsi command to - * the LLD. When the driver is finished processing the command - * the done callback is invoked. - * - * This is called to inform the LLD to transfer - * scsi_bufflen(cmd) bytes. scsi_sg_count(cmd) speciefies the - * number of scatterlist entried in the command and - * scsi_sglist(cmd) returns the scatterlist. - * - * return values: see queuecommand - * - * If the LLD accepts the cmd, it should set the result to an - * appropriate value when completed before calling the done function. - * - * STATUS: REQUIRED FOR TARGET DRIVERS - */ - /* TODO: rename */ - int (* transfer_response)(struct scsi_cmnd *, - void (*done)(struct scsi_cmnd *)); - - /* * This is an error handling strategy routine. You don't need to * define one of these if you don't want to - there is a default * routine that is present that should work in most cases. For those @@ -408,7 +388,7 @@ struct scsi_host_template { /* * Set this if the host adapter has limitations beside segment count. */ - unsigned short max_sectors; + unsigned int max_sectors; /* * DMA scatter gather segment boundary limit. A segment crossing this @@ -531,6 +511,9 @@ struct scsi_host_template { */ unsigned int cmd_size; struct scsi_host_cmd_pool *cmd_pool; + + /* temporary flag to disable blk-mq I/O path */ + bool disable_blk_mq; }; /* @@ -601,15 +584,16 @@ struct Scsi_Host { * Area to keep a shared tag map (if needed, will be * NULL if not). */ - struct blk_queue_tag *bqt; + union { + struct blk_queue_tag *bqt; + struct blk_mq_tag_set tag_set; + }; - /* - * The following two fields are protected with host_lock; - * however, eh routines can safely access during eh processing - * without acquiring the lock. - */ - unsigned int host_busy; /* commands actually active on low-level */ - unsigned int host_failed; /* commands that failed. */ + atomic_t host_busy; /* commands actually active on low-level */ + atomic_t host_blocked; + + unsigned int host_failed; /* commands that failed. + protected by host_lock */ unsigned int host_eh_scheduled; /* EH scheduled without command */ unsigned int host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ @@ -623,11 +607,11 @@ struct Scsi_Host { * These three parameters can be used to allow for wide scsi, * and for host adapters that support multiple busses * The first two should be set to 1 more than the actual max id - * or lun (i.e. 8 for normal systems). + * or lun (e.g. 8 for SCSI parallel systems). */ - unsigned int max_id; - unsigned int max_lun; unsigned int max_channel; + unsigned int max_id; + u64 max_lun; /* * This is a unique identifier that must be assigned so that we @@ -652,7 +636,7 @@ struct Scsi_Host { short cmd_per_lun; short unsigned int sg_tablesize; short unsigned int sg_prot_tablesize; - short unsigned int max_sectors; + unsigned int max_sectors; unsigned long dma_boundary; /* * Used to assign serial numbers to the cmds. @@ -695,6 +679,8 @@ struct Scsi_Host { /* The controller does not support WRITE SAME */ unsigned no_write_same:1; + unsigned use_blk_mq:1; + /* * Optional work queue to be utilized by the transport */ @@ -707,11 +693,6 @@ struct Scsi_Host { struct workqueue_struct *tmf_work_q; /* - * Host has rejected a command because it was busy. - */ - unsigned int host_blocked; - - /* * Value host_blocked counts down from */ unsigned int max_host_blocked; @@ -800,6 +781,13 @@ static inline int scsi_host_in_recovery(struct Scsi_Host *shost) shost->tmf_in_progress; } +extern bool scsi_use_blk_mq; + +static inline bool shost_use_blk_mq(struct Scsi_Host *shost) +{ + return shost->use_blk_mq; +} + extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *); extern void scsi_flush_work(struct Scsi_Host *); @@ -816,8 +804,6 @@ extern struct Scsi_Host *scsi_host_lookup(unsigned short); extern const char *scsi_host_state_name(enum scsi_host_state); extern void scsi_cmd_get_serial(struct Scsi_Host *, struct scsi_cmnd *); -extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *); - static inline int __must_check scsi_add_host(struct Scsi_Host *host, struct device *dev) { diff --git a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h index 81dd12edc38c..cdcc90b07ecb 100644 --- a/include/scsi/scsi_tcq.h +++ b/include/scsi/scsi_tcq.h @@ -67,7 +67,8 @@ static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth) if (!sdev->tagged_supported) return; - if (!blk_queue_tagged(sdev->request_queue)) + if (!shost_use_blk_mq(sdev->host) && + blk_queue_tagged(sdev->request_queue)) blk_queue_init_tags(sdev->request_queue, depth, sdev->host->bqt); @@ -80,7 +81,8 @@ static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth) **/ static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth) { - if (blk_queue_tagged(sdev->request_queue)) + if (!shost_use_blk_mq(sdev->host) && + blk_queue_tagged(sdev->request_queue)) blk_queue_free_tags(sdev->request_queue); scsi_adjust_queue_depth(sdev, 0, depth); } @@ -108,6 +110,15 @@ static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg) return 0; } +static inline struct scsi_cmnd *scsi_mq_find_tag(struct Scsi_Host *shost, + unsigned int hw_ctx, int tag) +{ + struct request *req; + + req = blk_mq_tag_to_rq(shost->tag_set.tags[hw_ctx], tag); + return req ? (struct scsi_cmnd *)req->special : NULL; +} + /** * scsi_find_tag - find a tagged command by device * @SDpnt: pointer to the ScSI device @@ -118,10 +129,12 @@ static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg) **/ static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag) { - struct request *req; if (tag != SCSI_NO_TAG) { + if (shost_use_blk_mq(sdev->host)) + return scsi_mq_find_tag(sdev->host, 0, tag); + req = blk_queue_find_tag(sdev->request_queue, tag); return req ? (struct scsi_cmnd *)req->special : NULL; } @@ -130,6 +143,7 @@ static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag) return sdev->current_cmnd; } + /** * scsi_init_shared_tag_map - create a shared tag map * @shost: the host to share the tag map among all devices @@ -138,6 +152,12 @@ static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag) static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth) { /* + * We always have a shared tag map around when using blk-mq. + */ + if (shost_use_blk_mq(shost)) + return 0; + + /* * If the shared tag map isn't already initialized, do it now. * This saves callers from having to check ->bqt when setting up * devices on the shared host (for libata) @@ -165,6 +185,8 @@ static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost, struct request *req; if (tag != SCSI_NO_TAG) { + if (shost_use_blk_mq(shost)) + return scsi_mq_find_tag(shost, 0, tag); req = blk_map_queue_find_tag(shost->bqt, tag); return req ? (struct scsi_cmnd *)req->special : NULL; } diff --git a/include/scsi/scsi_tgt.h b/include/scsi/scsi_tgt.h deleted file mode 100644 index d0fefb96158f..000000000000 --- a/include/scsi/scsi_tgt.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SCSI target definitions - */ - -#include <linux/dma-mapping.h> - -struct Scsi_Host; -struct scsi_cmnd; -struct scsi_lun; - -extern struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *); -extern int scsi_tgt_alloc_queue(struct Scsi_Host *); -extern void scsi_tgt_free_queue(struct Scsi_Host *); -extern int scsi_tgt_queue_command(struct scsi_cmnd *, u64, struct scsi_lun *, u64); -extern int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *, u64, int, u64, - struct scsi_lun *, void *); -extern struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *, - enum dma_data_direction, gfp_t); -extern void scsi_host_put_command(struct Scsi_Host *, struct scsi_cmnd *); -extern int scsi_tgt_it_nexus_create(struct Scsi_Host *, u64, char *); -extern int scsi_tgt_it_nexus_destroy(struct Scsi_Host *, u64); diff --git a/include/scsi/scsi_tgt_if.h b/include/scsi/scsi_tgt_if.h deleted file mode 100644 index f2ee7c238a45..000000000000 --- a/include/scsi/scsi_tgt_if.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * SCSI target kernel/user interface - * - * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org> - * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef __SCSI_TARGET_IF_H -#define __SCSI_TARGET_IF_H - -/* user -> kernel */ -#define TGT_UEVENT_CMD_RSP 0x0001 -#define TGT_UEVENT_IT_NEXUS_RSP 0x0002 -#define TGT_UEVENT_TSK_MGMT_RSP 0x0003 - -/* kernel -> user */ -#define TGT_KEVENT_CMD_REQ 0x1001 -#define TGT_KEVENT_CMD_DONE 0x1002 -#define TGT_KEVENT_IT_NEXUS_REQ 0x1003 -#define TGT_KEVENT_TSK_MGMT_REQ 0x1004 - -struct tgt_event_hdr { - uint16_t version; - uint16_t status; - uint16_t type; - uint16_t len; -} __attribute__ ((aligned (sizeof(uint64_t)))); - -struct tgt_event { - struct tgt_event_hdr hdr; - - union { - /* user-> kernel */ - struct { - int host_no; - int result; - aligned_u64 itn_id; - aligned_u64 tag; - aligned_u64 uaddr; - aligned_u64 sense_uaddr; - uint32_t len; - uint32_t sense_len; - uint8_t rw; - } cmd_rsp; - struct { - int host_no; - int result; - aligned_u64 itn_id; - aligned_u64 mid; - } tsk_mgmt_rsp; - struct { - __s32 host_no; - __s32 result; - aligned_u64 itn_id; - __u32 function; - } it_nexus_rsp; - - /* kernel -> user */ - struct { - int host_no; - uint32_t data_len; - aligned_u64 itn_id; - uint8_t scb[16]; - uint8_t lun[8]; - int attribute; - aligned_u64 tag; - } cmd_req; - struct { - int host_no; - int result; - aligned_u64 itn_id; - aligned_u64 tag; - } cmd_done; - struct { - int host_no; - int function; - aligned_u64 itn_id; - aligned_u64 tag; - uint8_t lun[8]; - aligned_u64 mid; - } tsk_mgmt_req; - struct { - __s32 host_no; - __u32 function; - aligned_u64 itn_id; - __u32 max_cmds; - __u8 initiator_id[16]; - } it_nexus_req; - } p; -} __attribute__ ((aligned (sizeof(uint64_t)))); - -#define TGT_RING_SIZE (1UL << 16) - -#endif diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h index af244f4bba53..81292392adbc 100644 --- a/include/scsi/scsi_transport.h +++ b/include/scsi/scsi_transport.h @@ -35,7 +35,7 @@ struct scsi_transport_template { /* * If set, called from sysfs and legacy procfs rescanning code. */ - int (*user_scan)(struct Scsi_Host *, uint, uint, uint); + int (*user_scan)(struct Scsi_Host *, uint, uint, u64); /* The size of the specific transport attribute structure (a * space of this size will be left at the end of the diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index 8c79980dc8f2..007a0bc01b74 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -131,6 +131,10 @@ enum fc_vport_state { #define FC_PORTSPEED_8GBIT 0x10 #define FC_PORTSPEED_16GBIT 0x20 #define FC_PORTSPEED_32GBIT 0x40 +#define FC_PORTSPEED_20GBIT 0x80 +#define FC_PORTSPEED_40GBIT 0x100 +#define FC_PORTSPEED_50GBIT 0x200 +#define FC_PORTSPEED_100GBIT 0x400 #define FC_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */ /* diff --git a/include/scsi/sg.h b/include/scsi/sg.h index a9f3c6fc3f57..9859355a7cf9 100644 --- a/include/scsi/sg.h +++ b/include/scsi/sg.h @@ -4,77 +4,34 @@ #include <linux/compiler.h> /* - History: - Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user - process control of SCSI devices. - Development Sponsored by Killy Corp. NY NY -Original driver (sg.h): -* Copyright (C) 1992 Lawrence Foard -Version 2 and 3 extensions to driver: -* Copyright (C) 1998 - 2006 Douglas Gilbert - - Version: 3.5.34 (20060920) - This version is for 2.6 series kernels. - - For a full changelog see http://www.torque.net/sg - -Map of SG verions to the Linux kernels in which they appear: - ---------- ---------------------------------- - original all kernels < 2.2.6 - 2.1.40 2.2.20 - 3.0.x optional version 3 sg driver for 2.2 series - 3.1.17++ 2.4.0++ - 3.5.30++ 2.6.0++ - -Major new features in SG 3.x driver (cf SG 2.x drivers) - - SG_IO ioctl() combines function if write() and read() - - new interface (sg_io_hdr_t) but still supports old interface - - scatter/gather in user space, direct IO, and mmap supported - - The normal action of this driver is to use the adapter (HBA) driver to DMA - data into kernel buffers and then use the CPU to copy the data into the - user space (vice versa for writes). That is called "indirect" IO due to - the double handling of data. There are two methods offered to remove the - redundant copy: 1) direct IO and 2) using the mmap() system call to map - the reserve buffer (this driver has one reserve buffer per fd) into the - user space. Both have their advantages. - In terms of absolute speed mmap() is faster. If speed is not a concern, - indirect IO should be fine. Read the documentation for more information. - - ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' or - 'echo 1 > /sys/module/sg/parameters/allow_dio' is needed. - That attribute is 0 by default. ** - - Historical note: this SCSI pass-through driver has been known as "sg" for - a decade. In broader kernel discussions "sg" is used to refer to scatter - gather techniques. The context should clarify which "sg" is referred to. - - Documentation - ============= - A web site for the SG device driver can be found at: - http://www.torque.net/sg [alternatively check the MAINTAINERS file] - The documentation for the sg version 3 driver can be found at: - http://www.torque.net/sg/p/sg_v3_ho.html - This is a rendering from DocBook source [change the extension to "sgml" - or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon). - The SG_IO ioctl is now found in other parts kernel (e.g. the block layer). - For more information see http://www.torque.net/sg/sg_io.html - - The older, version 2 documents discuss the original sg interface in detail: - http://www.torque.net/sg/p/scsi-generic.txt - http://www.torque.net/sg/p/scsi-generic_long.txt - Also available: <kernel_source>/Documentation/scsi/scsi-generic.txt - - Utility and test programs are available at the sg web site. They are - packaged as sg3_utils (for the lk 2.4 and 2.6 series) and sg_utils - (for the lk 2.2 series). -*/ + * History: + * Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user + * process control of SCSI devices. + * Development Sponsored by Killy Corp. NY NY + * + * Original driver (sg.h): + * Copyright (C) 1992 Lawrence Foard + * Version 2 and 3 extensions to driver: + * Copyright (C) 1998 - 2014 Douglas Gilbert + * + * Version: 3.5.36 (20140603) + * This version is for 2.6 and 3 series kernels. + * + * Documentation + * ============= + * A web site for the SG device driver can be found at: + * http://sg.danny.cz/sg [alternatively check the MAINTAINERS file] + * The documentation for the sg version 3 driver can be found at: + * http://sg.danny.cz/sg/p/sg_v3_ho.html + * Also see: <kernel_source>/Documentation/scsi/scsi-generic.txt + * + * For utility and test programs see: http://sg.danny.cz/sg/sg3_utils.html + */ #ifdef __KERNEL__ extern int sg_big_buff; /* for sysctl */ #endif -/* New interface introduced in the 3.x SG drivers follows */ typedef struct sg_iovec /* same structure as used by readv() Linux system */ { /* call. It defines one scatter-gather element. */ @@ -87,7 +44,7 @@ typedef struct sg_io_hdr { int interface_id; /* [i] 'S' for SCSI generic (required) */ int dxfer_direction; /* [i] data transfer direction */ - unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ + unsigned char cmd_len; /* [i] SCSI command length */ unsigned char mx_sb_len; /* [i] max length to write to sbp */ unsigned short iovec_count; /* [i] 0 implies no scatter gather */ unsigned int dxfer_len; /* [i] byte count of data transfer */ @@ -129,6 +86,7 @@ typedef struct sg_io_hdr #define SG_FLAG_MMAP_IO 4 /* request memory mapped IO */ #define SG_FLAG_NO_DXFER 0x10000 /* no transfer of kernel buffers to/from */ /* user space (debug indirect IO) */ +#define SG_FLAG_Q_AT_TAIL 0x10 /* default is Q_AT_HEAD */ /* following 'info' values are "or"-ed together */ #define SG_INFO_OK_MASK 0x1 |