diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 61 |
1 files changed, 38 insertions, 23 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index b12cb81ad8a2..3c86e27f094d 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -4,7 +4,7 @@ * * Implementation of FSF commands. * - * Copyright IBM Corp. 2002, 2017 + * Copyright IBM Corp. 2002, 2018 */ #define KMSG_COMPONENT "zfcp" @@ -437,6 +437,9 @@ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) #define ZFCP_FSF_PORTSPEED_10GBIT (1 << 3) #define ZFCP_FSF_PORTSPEED_8GBIT (1 << 4) #define ZFCP_FSF_PORTSPEED_16GBIT (1 << 5) +#define ZFCP_FSF_PORTSPEED_32GBIT (1 << 6) +#define ZFCP_FSF_PORTSPEED_64GBIT (1 << 7) +#define ZFCP_FSF_PORTSPEED_128GBIT (1 << 8) #define ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED (1 << 15) static u32 zfcp_fsf_convert_portspeed(u32 fsf_speed) @@ -454,6 +457,12 @@ static u32 zfcp_fsf_convert_portspeed(u32 fsf_speed) fdmi_speed |= FC_PORTSPEED_8GBIT; if (fsf_speed & ZFCP_FSF_PORTSPEED_16GBIT) fdmi_speed |= FC_PORTSPEED_16GBIT; + if (fsf_speed & ZFCP_FSF_PORTSPEED_32GBIT) + fdmi_speed |= FC_PORTSPEED_32GBIT; + if (fsf_speed & ZFCP_FSF_PORTSPEED_64GBIT) + fdmi_speed |= FC_PORTSPEED_64GBIT; + if (fsf_speed & ZFCP_FSF_PORTSPEED_128GBIT) + fdmi_speed |= FC_PORTSPEED_128GBIT; if (fsf_speed & ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED) fdmi_speed |= FC_PORTSPEED_NOT_NEGOTIATED; return fdmi_speed; @@ -662,7 +671,7 @@ static struct zfcp_fsf_req *zfcp_fsf_alloc(mempool_t *pool) return req; } -static struct fsf_qtcb *zfcp_qtcb_alloc(mempool_t *pool) +static struct fsf_qtcb *zfcp_fsf_qtcb_alloc(mempool_t *pool) { struct fsf_qtcb *qtcb; @@ -701,9 +710,10 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_qdio *qdio, if (likely(fsf_cmd != FSF_QTCB_UNSOLICITED_STATUS)) { if (likely(pool)) - req->qtcb = zfcp_qtcb_alloc(adapter->pool.qtcb_pool); + req->qtcb = zfcp_fsf_qtcb_alloc( + adapter->pool.qtcb_pool); else - req->qtcb = zfcp_qtcb_alloc(NULL); + req->qtcb = zfcp_fsf_qtcb_alloc(NULL); if (unlikely(!req->qtcb)) { zfcp_fsf_req_free(req); @@ -2036,10 +2046,14 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) sizeof(blktrc)); } -static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req) +/** + * zfcp_fsf_fcp_handler_common() - FCP response handler common to I/O and TMF. + * @req: Pointer to FSF request. + * @sdev: Pointer to SCSI device as request context. + */ +static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req, + struct scsi_device *sdev) { - struct scsi_cmnd *scmnd = req->data; - struct scsi_device *sdev = scmnd->device; struct zfcp_scsi_dev *zfcp_sdev; struct fsf_qtcb_header *header = &req->qtcb->header; @@ -2051,7 +2065,7 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req) switch (header->fsf_status) { case FSF_HANDLE_MISMATCH: case FSF_PORT_HANDLE_NOT_VALID: - zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fssfch1"); + zfcp_erp_adapter_reopen(req->adapter, 0, "fssfch1"); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_FCPLUN_NOT_VALID: @@ -2069,8 +2083,7 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req) req->qtcb->bottom.io.data_direction, (unsigned long long)zfcp_scsi_dev_lun(sdev), (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_adapter_shutdown(zfcp_sdev->port->adapter, 0, - "fssfch3"); + zfcp_erp_adapter_shutdown(req->adapter, 0, "fssfch3"); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_CMND_LENGTH_NOT_VALID: @@ -2080,8 +2093,7 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req) req->qtcb->bottom.io.fcp_cmnd_length, (unsigned long long)zfcp_scsi_dev_lun(sdev), (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_adapter_shutdown(zfcp_sdev->port->adapter, 0, - "fssfch4"); + zfcp_erp_adapter_shutdown(req->adapter, 0, "fssfch4"); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PORT_BOXED: @@ -2120,7 +2132,7 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) return; } - zfcp_fsf_fcp_handler_common(req); + zfcp_fsf_fcp_handler_common(req, scpnt->device); if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED); @@ -2258,7 +2270,7 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd) BUILD_BUG_ON(sizeof(struct fcp_cmnd) > FSF_FCP_CMND_SIZE); fcp_cmnd = &req->qtcb->bottom.io.fcp_cmnd.iu; - zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0); + zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd); if ((scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) && scsi_prot_sg_count(scsi_cmnd)) { @@ -2297,10 +2309,11 @@ out: static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req) { + struct scsi_device *sdev = req->data; struct fcp_resp_with_ext *fcp_rsp; struct fcp_resp_rsp_info *rsp_info; - zfcp_fsf_fcp_handler_common(req); + zfcp_fsf_fcp_handler_common(req, sdev); fcp_rsp = &req->qtcb->bottom.io.fcp_rsp.iu; rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1]; @@ -2311,17 +2324,18 @@ static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req) } /** - * zfcp_fsf_fcp_task_mgmt - send SCSI task management command - * @scmnd: SCSI command to send the task management command for - * @tm_flags: unsigned byte for task management flags - * Returns: on success pointer to struct fsf_req, NULL otherwise + * zfcp_fsf_fcp_task_mgmt() - Send SCSI task management command (TMF). + * @sdev: Pointer to SCSI device to send the task management command to. + * @tm_flags: Unsigned byte for task management flags. + * + * Return: On success pointer to struct zfcp_fsf_req, %NULL otherwise. */ -struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd, +struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device *sdev, u8 tm_flags) { struct zfcp_fsf_req *req = NULL; struct fcp_cmnd *fcp_cmnd; - struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scmnd->device); + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio; if (unlikely(!(atomic_read(&zfcp_sdev->status) & @@ -2341,7 +2355,8 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd, goto out; } - req->data = scmnd; + req->data = sdev; + req->handler = zfcp_fsf_fcp_task_mgmt_handler; req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; req->qtcb->header.port_handle = zfcp_sdev->port->handle; @@ -2352,7 +2367,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd, zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); fcp_cmnd = &req->qtcb->bottom.io.fcp_cmnd.iu; - zfcp_fc_scsi_to_fcp(fcp_cmnd, scmnd, tm_flags); + zfcp_fc_fcp_tm(fcp_cmnd, sdev, tm_flags); zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT); if (!zfcp_fsf_req_send(req)) |