[SCSI] tgt: add I_T nexus support
tgt uses scsi_host as I_T nexus. This works for ibmvstgt because it creates one scsi_host for one initiator. However, other target drivers don't work like that. This adds I_T nexus support, which enable one scsi_host to handle multiple initiators. New scsi_tgt_it_nexus_create/destroy functions are expected be called transport classes. For example, ibmvstgt creates an initiator remote port, then the srp transport calls tgt_it_nexus_create. tgt doesn't manages I_T nexus, instead it tells tgtd, user-space daemon, to create a new I_T nexus. On the receiving the response from tgtd, tgt calls shost->transportt->it_nexus_response. transports should notify a lld. The srp transport uses it_nexus_response callback in srp_function_template to do that. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:

committed by
James Bottomley

parent
aebd5e476e
commit
2c47f9efbe
@@ -146,7 +146,7 @@ struct scsi_host_template {
|
||||
void (*done)(struct scsi_cmnd *));
|
||||
|
||||
/* Used as callback for the completion of task management request. */
|
||||
int (* tsk_mgmt_response)(u64 mid, int result);
|
||||
int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64 mid, int result);
|
||||
|
||||
/*
|
||||
* This is an error handling strategy routine. You don't need to
|
||||
|
@@ -11,9 +11,11 @@ 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 *, struct scsi_lun *, u64);
|
||||
extern int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *, int, u64, struct scsi_lun *,
|
||||
void *);
|
||||
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);
|
||||
|
@@ -23,13 +23,15 @@
|
||||
#define __SCSI_TARGET_IF_H
|
||||
|
||||
/* user -> kernel */
|
||||
#define TGT_UEVENT_CMD_RSP 0x0001
|
||||
#define TGT_UEVENT_TSK_MGMT_RSP 0x0002
|
||||
#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_TSK_MGMT_REQ 0x1003
|
||||
#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;
|
||||
@@ -46,6 +48,7 @@ struct tgt_event {
|
||||
struct {
|
||||
int host_no;
|
||||
int result;
|
||||
aligned_u64 itn_id;
|
||||
aligned_u64 tag;
|
||||
aligned_u64 uaddr;
|
||||
aligned_u64 sense_uaddr;
|
||||
@@ -55,15 +58,22 @@ struct tgt_event {
|
||||
} cmd_rsp;
|
||||
struct {
|
||||
int host_no;
|
||||
aligned_u64 mid;
|
||||
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;
|
||||
@@ -71,16 +81,25 @@ struct tgt_event {
|
||||
} cmd_req;
|
||||
struct {
|
||||
int host_no;
|
||||
aligned_u64 tag;
|
||||
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))));
|
||||
|
||||
|
@@ -65,6 +65,12 @@ struct scsi_transport_template {
|
||||
* EH_NOT_HANDLED Begin normal error recovery
|
||||
*/
|
||||
enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *);
|
||||
|
||||
/*
|
||||
* Used as callback for the completion of i_t_nexus request
|
||||
* for target drivers.
|
||||
*/
|
||||
int (* it_nexus_response)(struct Scsi_Host *, u64, int);
|
||||
};
|
||||
|
||||
#define transport_class_to_shost(tc) \
|
||||
|
Reference in New Issue
Block a user