From: Linus Torvalds Date: Thu, 6 Jul 2017 19:10:33 +0000 (-0700) Subject: Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=90311148415ab23f5767fbb577a012d4405f12e5;p=openwrt%2Fstaging%2Fblogic.git Merge tag 'scsi-misc' of git://git./linux/kernel/git/jejb/scsi Pull SCSI updates from James Bottomley: "This is mostly updates of the usual suspects: lpfc, qla2xxx, bnx2fc, qedf, hpsa, hisi_sas, smartpqi, cxlflash, aacraid, csiostor along with a host of minor and miscellaneous changes" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (276 commits) qla2xxx: Fix NVMe entry_type for iocb packet on BE system scsi: qla2xxx: avoid unused-function warning scsi: snic: fix a couple of spelling mistakes/typos scsi: qla2xxx: fix a bunch of typos and spelling mistakes scsi: lpfc: don't double count abort errors scsi: lpfc: spin_lock_irq() is not nestable scsi: hisi_sas: optimise DMA slot memory scsi: ibmvfc: constify dev_pm_ops structures. scsi: ibmvscsi: constify dev_pm_ops structures. scsi: cxlflash: Update debug prints in reset handlers scsi: cxlflash: Update send_tmf() parameters scsi: cxlflash: Avoid double free of character device scsi: Add STARGET_CREATED_REMOVE state to scsi_target_state scsi: ses: do not add a device to an enclosure if enclosure_add_links() fails. scsi: ufs: flush eh_work when eh_work scheduled. scsi: qla2xxx: Protect access to qpair members with qpair->qp_lock scsi: sun_esp: fix device reference leaks scsi: fnic: changing queue command to return result DID_IMM_RETRY when rport is init scsi: fnic: correct speed display and add support for 25,40 and 100G scsi: fnic: added timestamp reporting in fnic debug stats ... --- 90311148415ab23f5767fbb577a012d4405f12e5 diff --cc drivers/scsi/scsi_lib.c index 550e29f903b7,41c19c75dab4..f6097b89d5d3 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@@ -1116,20 -1124,35 +1106,49 @@@ err_exit } EXPORT_SYMBOL(scsi_init_io); +/** + * scsi_initialize_rq - initialize struct scsi_cmnd.req + * + * Called from inside blk_get_request(). + */ +void scsi_initialize_rq(struct request *rq) +{ + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); + + scsi_req_init(&cmd->req); +} +EXPORT_SYMBOL(scsi_initialize_rq); + + /* Add a command to the list used by the aacraid and dpt_i2o drivers */ + void scsi_add_cmd_to_list(struct scsi_cmnd *cmd) + { + struct scsi_device *sdev = cmd->device; + struct Scsi_Host *shost = sdev->host; + unsigned long flags; + + if (shost->use_cmd_list) { + spin_lock_irqsave(&sdev->list_lock, flags); + list_add_tail(&cmd->list, &sdev->cmd_list); + spin_unlock_irqrestore(&sdev->list_lock, flags); + } + } + + /* Remove a command from the list used by the aacraid and dpt_i2o drivers */ + void scsi_del_cmd_from_list(struct scsi_cmnd *cmd) + { + struct scsi_device *sdev = cmd->device; + struct Scsi_Host *shost = sdev->host; + unsigned long flags; + + if (shost->use_cmd_list) { + spin_lock_irqsave(&sdev->list_lock, flags); + BUG_ON(list_empty(&cmd->list)); + list_del_init(&cmd->list); + spin_unlock_irqrestore(&sdev->list_lock, flags); + } + } + +/* Called after a request has been started. */ void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd) { void *buf = cmd->sense_buffer; @@@ -2974,10 -2989,7 +2989,7 @@@ int scsi_internal_device_block_nowait(s * request queue. */ if (q->mq_ops) { - if (wait) - blk_mq_quiesce_queue(q); - else - blk_mq_quiesce_queue_nowait(q); - blk_mq_stop_hw_queues(q); ++ blk_mq_quiesce_queue_nowait(q); } else { spin_lock_irqsave(q->queue_lock, flags); blk_stop_queue(q); @@@ -2988,31 -2998,77 +2998,77 @@@ return 0; } - EXPORT_SYMBOL_GPL(scsi_internal_device_block); - + EXPORT_SYMBOL_GPL(scsi_internal_device_block_nowait); + /** - * scsi_internal_device_unblock - resume a device after a block request - * @sdev: device to resume - * @new_state: state to set devices to after unblocking + * scsi_internal_device_block - try to transition to the SDEV_BLOCK state + * @sdev: device to block + * + * Pause SCSI command processing on the specified device and wait until all + * ongoing scsi_request_fn() / scsi_queue_rq() calls have finished. May sleep. * - * Called by scsi lld's or the midlayer to restart the device queue - * for the previously suspended scsi device. Called from interrupt or - * normal process context. + * Returns zero if successful or a negative error code upon failure. * - * Returns zero if successful or error if not. + * Note: + * This routine transitions the device to the SDEV_BLOCK state (which must be + * a legal transition). When the device is in this state, command processing + * is paused until the device leaves the SDEV_BLOCK state. See also + * scsi_internal_device_unblock(). * - * Notes: - * This routine transitions the device to the SDEV_RUNNING state - * or to one of the offline states (which must be a legal transition) - * allowing the midlayer to goose the queue for this device. + * To do: avoid that scsi_send_eh_cmnd() calls queuecommand() after + * scsi_internal_device_block() has blocked a SCSI device and also + * remove the rport mutex lock and unlock calls from srp_queuecommand(). */ - int - scsi_internal_device_unblock(struct scsi_device *sdev, - enum scsi_device_state new_state) + static int scsi_internal_device_block(struct scsi_device *sdev) { - struct request_queue *q = sdev->request_queue; + struct request_queue *q = sdev->request_queue; + int err; + + mutex_lock(&sdev->state_mutex); + err = scsi_internal_device_block_nowait(sdev); + if (err == 0) { + if (q->mq_ops) + blk_mq_quiesce_queue(q); + else + scsi_wait_for_queuecommand(sdev); + } + mutex_unlock(&sdev->state_mutex); + + return err; + } + + void scsi_start_queue(struct scsi_device *sdev) + { + struct request_queue *q = sdev->request_queue; unsigned long flags; + if (q->mq_ops) { - blk_mq_start_stopped_hw_queues(q, false); ++ blk_mq_unquiesce_queue(q); + } else { + spin_lock_irqsave(q->queue_lock, flags); + blk_start_queue(q); + spin_unlock_irqrestore(q->queue_lock, flags); + } + } + + /** + * scsi_internal_device_unblock_nowait - resume a device after a block request + * @sdev: device to resume + * @new_state: state to set the device to after unblocking + * + * Restart the device queue for a previously suspended SCSI device. Does not + * sleep. + * + * Returns zero if successful or a negative error code upon failure. + * + * Notes: + * This routine transitions the device to the SDEV_RUNNING state or to one of + * the offline states (which must be a legal transition) allowing the midlayer + * to goose the queue for this device. + */ + int scsi_internal_device_unblock_nowait(struct scsi_device *sdev, + enum scsi_device_state new_state) + { /* * Try to transition the scsi device to SDEV_RUNNING or one of the * offlined states and goose the device queue if successful. diff --cc drivers/scsi/scsi_transport_fc.c index 1df77453f6b6,6dd0922a499d..7e24aa30c3b0 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@@ -2914,18 -2914,16 +2914,18 @@@ EXPORT_SYMBOL(fc_remote_port_add) * port is no longer part of the topology. Note: Although a port * may no longer be part of the topology, it may persist in the remote * ports displayed by the fc_host. We do this under 2 conditions: + * * 1) If the port was a scsi target, we delay its deletion by "blocking" it. - * This allows the port to temporarily disappear, then reappear without - * disrupting the SCSI device tree attached to it. During the "blocked" - * period the port will still exist. + * This allows the port to temporarily disappear, then reappear without + * disrupting the SCSI device tree attached to it. During the "blocked" + * period the port will still exist. + * * 2) If the port was a scsi target and disappears for longer than we - * expect, we'll delete the port and the tear down the SCSI device tree - * attached to it. However, we want to semi-persist the target id assigned - * to that port if it eventually does exist. The port structure will - * remain (although with minimal information) so that the target id - * bindings also remain. + * expect, we'll delete the port and the tear down the SCSI device tree + * attached to it. However, we want to semi-persist the target id assigned + * to that port if it eventually does exist. The port structure will + * remain (although with minimal information) so that the target id - * bindings remails. ++ * bindings also remain. * * If the remote port is not an FCP Target, it will be fully torn down * and deallocated, including the fc_remote_port class device.