aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ibmvscsi
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2009-05-28 17:17:30 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-08 14:07:45 -0400
commit497f9c504f76e7a751cd370604e1c8521743746d (patch)
treeba7c6a0bb9044d1d6b723c99c028b5d8121344e9 /drivers/scsi/ibmvscsi
parent79111d0899a122fa3cf0a2921292c3e6a25452d0 (diff)
[SCSI] ibmvfc: Add flush on halt support
The virtual I/O server controlling the NPIV adapter associated with a virtual fibre channel adapter can send a HALT event to the client. When this occurs, the client can no longer send commands until a RESUME is received. By adding support for flush on halt, we will get all of our outstanding commands flushed back before the Virtual I/O server enters the halt state, eliminating potential command timeouts for outstanding commands which might occur if we did not support this feature. Signed-off-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/ibmvscsi')
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c34
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h13
2 files changed, 42 insertions, 5 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 6eb3b75eec93..04d97d9e3cea 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -110,7 +110,7 @@ static const struct {
110 { IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_DEAD, DID_ERROR, 0, 1, "transport dead" }, 110 { IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_DEAD, DID_ERROR, 0, 1, "transport dead" },
111 { IBMVFC_FABRIC_MAPPED, IBMVFC_CONFIG_ERROR, DID_ERROR, 1, 1, "configuration error" }, 111 { IBMVFC_FABRIC_MAPPED, IBMVFC_CONFIG_ERROR, DID_ERROR, 1, 1, "configuration error" },
112 { IBMVFC_FABRIC_MAPPED, IBMVFC_NAME_SERVER_FAIL, DID_ERROR, 1, 1, "name server failure" }, 112 { IBMVFC_FABRIC_MAPPED, IBMVFC_NAME_SERVER_FAIL, DID_ERROR, 1, 1, "name server failure" },
113 { IBMVFC_FABRIC_MAPPED, IBMVFC_LINK_HALTED, DID_REQUEUE, 0, 0, "link halted" }, 113 { IBMVFC_FABRIC_MAPPED, IBMVFC_LINK_HALTED, DID_REQUEUE, 1, 0, "link halted" },
114 { IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_GENERAL, DID_OK, 1, 0, "general transport error" }, 114 { IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_GENERAL, DID_OK, 1, 0, "general transport error" },
115 115
116 { IBMVFC_VIOS_FAILURE, IBMVFC_CRQ_FAILURE, DID_REQUEUE, 1, 1, "CRQ failure" }, 116 { IBMVFC_VIOS_FAILURE, IBMVFC_CRQ_FAILURE, DID_REQUEUE, 1, 1, "CRQ failure" },
@@ -1169,8 +1169,9 @@ static void ibmvfc_set_login_info(struct ibmvfc_host *vhost)
1169 login_info->partition_num = vhost->partition_number; 1169 login_info->partition_num = vhost->partition_number;
1170 login_info->vfc_frame_version = 1; 1170 login_info->vfc_frame_version = 1;
1171 login_info->fcp_version = 3; 1171 login_info->fcp_version = 3;
1172 login_info->flags = IBMVFC_FLUSH_ON_HALT;
1172 if (vhost->client_migrated) 1173 if (vhost->client_migrated)
1173 login_info->flags = IBMVFC_CLIENT_MIGRATED; 1174 login_info->flags |= IBMVFC_CLIENT_MIGRATED;
1174 1175
1175 login_info->max_cmds = max_requests + IBMVFC_NUM_INTERNAL_REQ; 1176 login_info->max_cmds = max_requests + IBMVFC_NUM_INTERNAL_REQ;
1176 login_info->capabilities = IBMVFC_CAN_MIGRATE; 1177 login_info->capabilities = IBMVFC_CAN_MIGRATE;
@@ -2185,8 +2186,25 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
2185 " node_name: %llx\n", desc, crq->scsi_id, crq->wwpn, crq->node_name); 2186 " node_name: %llx\n", desc, crq->scsi_id, crq->wwpn, crq->node_name);
2186 2187
2187 switch (crq->event) { 2188 switch (crq->event) {
2188 case IBMVFC_AE_LINK_UP:
2189 case IBMVFC_AE_RESUME: 2189 case IBMVFC_AE_RESUME:
2190 switch (crq->link_state) {
2191 case IBMVFC_AE_LS_LINK_DOWN:
2192 ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
2193 break;
2194 case IBMVFC_AE_LS_LINK_DEAD:
2195 ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
2196 break;
2197 case IBMVFC_AE_LS_LINK_UP:
2198 case IBMVFC_AE_LS_LINK_BOUNCED:
2199 default:
2200 vhost->events_to_log |= IBMVFC_AE_LINKUP;
2201 vhost->delay_init = 1;
2202 __ibmvfc_reset_host(vhost);
2203 break;
2204 };
2205
2206 break;
2207 case IBMVFC_AE_LINK_UP:
2190 vhost->events_to_log |= IBMVFC_AE_LINKUP; 2208 vhost->events_to_log |= IBMVFC_AE_LINKUP;
2191 vhost->delay_init = 1; 2209 vhost->delay_init = 1;
2192 __ibmvfc_reset_host(vhost); 2210 __ibmvfc_reset_host(vhost);
@@ -2505,6 +2523,14 @@ static ssize_t ibmvfc_show_host_npiv_version(struct device *dev,
2505 return snprintf(buf, PAGE_SIZE, "%d\n", vhost->login_buf->resp.version); 2523 return snprintf(buf, PAGE_SIZE, "%d\n", vhost->login_buf->resp.version);
2506} 2524}
2507 2525
2526static ssize_t ibmvfc_show_host_capabilities(struct device *dev,
2527 struct device_attribute *attr, char *buf)
2528{
2529 struct Scsi_Host *shost = class_to_shost(dev);
2530 struct ibmvfc_host *vhost = shost_priv(shost);
2531 return snprintf(buf, PAGE_SIZE, "%llx\n", vhost->login_buf->resp.capabilities);
2532}
2533
2508/** 2534/**
2509 * ibmvfc_show_log_level - Show the adapter's error logging level 2535 * ibmvfc_show_log_level - Show the adapter's error logging level
2510 * @dev: class device struct 2536 * @dev: class device struct
@@ -2554,6 +2580,7 @@ static DEVICE_ATTR(device_name, S_IRUGO, ibmvfc_show_host_device_name, NULL);
2554static DEVICE_ATTR(port_loc_code, S_IRUGO, ibmvfc_show_host_loc_code, NULL); 2580static DEVICE_ATTR(port_loc_code, S_IRUGO, ibmvfc_show_host_loc_code, NULL);
2555static DEVICE_ATTR(drc_name, S_IRUGO, ibmvfc_show_host_drc_name, NULL); 2581static DEVICE_ATTR(drc_name, S_IRUGO, ibmvfc_show_host_drc_name, NULL);
2556static DEVICE_ATTR(npiv_version, S_IRUGO, ibmvfc_show_host_npiv_version, NULL); 2582static DEVICE_ATTR(npiv_version, S_IRUGO, ibmvfc_show_host_npiv_version, NULL);
2583static DEVICE_ATTR(capabilities, S_IRUGO, ibmvfc_show_host_capabilities, NULL);
2557static DEVICE_ATTR(log_level, S_IRUGO | S_IWUSR, 2584static DEVICE_ATTR(log_level, S_IRUGO | S_IWUSR,
2558 ibmvfc_show_log_level, ibmvfc_store_log_level); 2585 ibmvfc_show_log_level, ibmvfc_store_log_level);
2559 2586
@@ -2609,6 +2636,7 @@ static struct device_attribute *ibmvfc_attrs[] = {
2609 &dev_attr_port_loc_code, 2636 &dev_attr_port_loc_code,
2610 &dev_attr_drc_name, 2637 &dev_attr_drc_name,
2611 &dev_attr_npiv_version, 2638 &dev_attr_npiv_version,
2639 &dev_attr_capabilities,
2612 &dev_attr_log_level, 2640 &dev_attr_log_level,
2613 NULL 2641 NULL
2614}; 2642};
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index 6adaad80565d..cf26380820fb 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -207,7 +207,8 @@ struct ibmvfc_npiv_login_resp {
207#define IBMVFC_NATIVE_FC 0x01 207#define IBMVFC_NATIVE_FC 0x01
208#define IBMVFC_CAN_FLUSH_ON_HALT 0x08 208#define IBMVFC_CAN_FLUSH_ON_HALT 0x08
209 u32 reserved; 209 u32 reserved;
210 u64 capabilites; 210 u64 capabilities;
211#define IBMVFC_CAN_FLUSH_ON_HALT 0x08
211 u32 max_cmds; 212 u32 max_cmds;
212 u32 scsi_id_sz; 213 u32 scsi_id_sz;
213 u64 max_dma_len; 214 u64 max_dma_len;
@@ -547,9 +548,17 @@ struct ibmvfc_crq_queue {
547 dma_addr_t msg_token; 548 dma_addr_t msg_token;
548}; 549};
549 550
551enum ibmvfc_ae_link_state {
552 IBMVFC_AE_LS_LINK_UP = 0x01,
553 IBMVFC_AE_LS_LINK_BOUNCED = 0x02,
554 IBMVFC_AE_LS_LINK_DOWN = 0x04,
555 IBMVFC_AE_LS_LINK_DEAD = 0x08,
556};
557
550struct ibmvfc_async_crq { 558struct ibmvfc_async_crq {
551 volatile u8 valid; 559 volatile u8 valid;
552 u8 pad[3]; 560 u8 link_state;
561 u8 pad[2];
553 u32 pad2; 562 u32 pad2;
554 volatile u64 event; 563 volatile u64 event;
555 volatile u64 scsi_id; 564 volatile u64 scsi_id;