diff options
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r-- | drivers/scsi/scsi.c | 210 |
1 files changed, 25 insertions, 185 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 79c77b485a67..9b3829931f40 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -527,9 +527,9 @@ void scsi_log_send(struct scsi_cmnd *cmd) * * 1: nothing (match completion) * - * 2: log opcode + command of all commands + * 2: log opcode + command of all commands + cmd address * - * 3: same as 2 plus dump cmd address + * 3: same as 2 * * 4: same as 3 plus dump extra junk */ @@ -537,10 +537,8 @@ void scsi_log_send(struct scsi_cmnd *cmd) level = SCSI_LOG_LEVEL(SCSI_LOG_MLQUEUE_SHIFT, SCSI_LOG_MLQUEUE_BITS); if (level > 1) { - scmd_printk(KERN_INFO, cmd, "Send: "); - if (level > 2) - printk("0x%p ", cmd); - printk("\n"); + scmd_printk(KERN_INFO, cmd, + "Send: scmd 0x%p\n", cmd); scsi_print_command(cmd); if (level > 3) { printk(KERN_INFO "buffer = 0x%p, bufflen = %d," @@ -565,7 +563,7 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) * * 2: same as 1 but for all command completions. * - * 3: same as 2 plus dump cmd address + * 3: same as 2 * * 4: same as 3 plus dump extra junk */ @@ -574,39 +572,10 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) SCSI_LOG_MLCOMPLETE_BITS); if (((level > 0) && (cmd->result || disposition != SUCCESS)) || (level > 1)) { - scmd_printk(KERN_INFO, cmd, "Done: "); - if (level > 2) - printk("0x%p ", cmd); - /* - * Dump truncated values, so we usually fit within - * 80 chars. - */ - switch (disposition) { - case SUCCESS: - printk("SUCCESS\n"); - break; - case NEEDS_RETRY: - printk("RETRY\n"); - break; - case ADD_TO_MLQUEUE: - printk("MLQUEUE\n"); - break; - case FAILED: - printk("FAILED\n"); - break; - case TIMEOUT_ERROR: - /* - * If called via scsi_times_out. - */ - printk("TIMEOUT\n"); - break; - default: - printk("UNKNOWN\n"); - } - scsi_print_result(cmd); + scsi_print_result(cmd, "Done: ", disposition); scsi_print_command(cmd); if (status_byte(cmd->result) & CHECK_CONDITION) - scsi_print_sense("", cmd); + scsi_print_sense(cmd); if (level > 3) scmd_printk(KERN_INFO, cmd, "scsi host busy %d failed %d\n", @@ -634,87 +603,6 @@ void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd) EXPORT_SYMBOL(scsi_cmd_get_serial); /** - * scsi_dispatch_command - Dispatch a command to the low-level driver. - * @cmd: command block we are dispatching. - * - * Return: nonzero return request was rejected and device's queue needs to be - * plugged. - */ -int scsi_dispatch_cmd(struct scsi_cmnd *cmd) -{ - struct Scsi_Host *host = cmd->device->host; - int rtn = 0; - - atomic_inc(&cmd->device->iorequest_cnt); - - /* check if the device is still usable */ - if (unlikely(cmd->device->sdev_state == SDEV_DEL)) { - /* in SDEV_DEL we error all commands. DID_NO_CONNECT - * returns an immediate error upwards, and signals - * that the device is no longer present */ - cmd->result = DID_NO_CONNECT << 16; - goto done; - } - - /* Check to see if the scsi lld made this device blocked. */ - if (unlikely(scsi_device_blocked(cmd->device))) { - /* - * in blocked state, the command is just put back on - * the device queue. The suspend state has already - * blocked the queue so future requests should not - * occur until the device transitions out of the - * suspend state. - */ - SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd, - "queuecommand : device blocked\n")); - return SCSI_MLQUEUE_DEVICE_BUSY; - } - - /* Store the LUN value in cmnd, if needed. */ - if (cmd->device->lun_in_cdb) - cmd->cmnd[1] = (cmd->cmnd[1] & 0x1f) | - (cmd->device->lun << 5 & 0xe0); - - scsi_log_send(cmd); - - /* - * Before we queue this command, check if the command - * length exceeds what the host adapter can handle. - */ - if (cmd->cmd_len > cmd->device->host->max_cmd_len) { - SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd, - "queuecommand : command too long. " - "cdb_size=%d host->max_cmd_len=%d\n", - cmd->cmd_len, cmd->device->host->max_cmd_len)); - cmd->result = (DID_ABORT << 16); - goto done; - } - - if (unlikely(host->shost_state == SHOST_DEL)) { - cmd->result = (DID_NO_CONNECT << 16); - goto done; - - } - - trace_scsi_dispatch_cmd_start(cmd); - rtn = host->hostt->queuecommand(host, cmd); - if (rtn) { - trace_scsi_dispatch_cmd_error(cmd, rtn); - if (rtn != SCSI_MLQUEUE_DEVICE_BUSY && - rtn != SCSI_MLQUEUE_TARGET_BUSY) - rtn = SCSI_MLQUEUE_HOST_BUSY; - - SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd, - "queuecommand : request rejected\n")); - } - - return rtn; - done: - cmd->scsi_done(cmd); - return 0; -} - -/** * scsi_finish_command - cleanup and pass command back to upper layer * @cmd: the command * @@ -773,32 +661,18 @@ void scsi_finish_command(struct scsi_cmnd *cmd) } /** - * scsi_adjust_queue_depth - Let low level drivers change a device's queue depth + * scsi_change_queue_depth - change a device's queue depth * @sdev: SCSI Device in question - * @tagged: Do we use tagged queueing (non-0) or do we treat - * this device as an untagged device (0) - * @tags: Number of tags allowed if tagged queueing enabled, - * or number of commands the low level driver can - * queue up in non-tagged mode (as per cmd_per_lun). - * - * Returns: Nothing + * @depth: number of commands allowed to be queued to the driver * - * Lock Status: None held on entry - * - * Notes: Low level drivers may call this at any time and we will do - * the right thing depending on whether or not the device is - * currently active and whether or not it even has the - * command blocks built yet. + * Sets the device queue depth and returns the new value. */ -void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags) +int scsi_change_queue_depth(struct scsi_device *sdev, int depth) { unsigned long flags; - /* - * refuse to set tagged depth to an unworkable size - */ - if (tags <= 0) - return; + if (depth <= 0) + goto out; spin_lock_irqsave(sdev->request_queue->queue_lock, flags); @@ -813,35 +687,17 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags) */ if (!shost_use_blk_mq(sdev->host) && !sdev->host->bqt) { if (blk_queue_tagged(sdev->request_queue) && - blk_queue_resize_tags(sdev->request_queue, tags) != 0) - goto out; + blk_queue_resize_tags(sdev->request_queue, depth) != 0) + goto out_unlock; } - sdev->queue_depth = tags; - switch (tagged) { - case 0: - sdev->ordered_tags = 0; - sdev->simple_tags = 0; - break; - case MSG_ORDERED_TAG: - sdev->ordered_tags = 1; - sdev->simple_tags = 1; - break; - case MSG_SIMPLE_TAG: - sdev->ordered_tags = 0; - sdev->simple_tags = 1; - break; - default: - sdev->ordered_tags = 0; - sdev->simple_tags = 0; - sdev_printk(KERN_WARNING, sdev, - "scsi_adjust_queue_depth, bad queue type, " - "disabled\n"); - } - out: + sdev->queue_depth = depth; +out_unlock: spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); +out: + return sdev->queue_depth; } -EXPORT_SYMBOL(scsi_adjust_queue_depth); +EXPORT_SYMBOL(scsi_change_queue_depth); /** * scsi_track_queue_full - track QUEUE_FULL events to adjust queue depth @@ -883,17 +739,8 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth) if (sdev->last_queue_full_count <= 10) return 0; - if (sdev->last_queue_full_depth < 8) { - /* Drop back to untagged */ - scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); - return -1; - } - - if (sdev->ordered_tags) - scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth); - else - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth); - return depth; + + return scsi_change_queue_depth(sdev, depth); } EXPORT_SYMBOL(scsi_track_queue_full); @@ -1139,9 +986,9 @@ int scsi_device_get(struct scsi_device *sdev) return -ENXIO; if (!get_device(&sdev->sdev_gendev)) return -ENXIO; - /* We can fail this if we're doing SCSI operations + /* We can fail try_module_get if we're doing SCSI operations * from module exit (like cache flush) */ - try_module_get(sdev->host->hostt->module); + __module_get(sdev->host->hostt->module); return 0; } @@ -1157,14 +1004,7 @@ EXPORT_SYMBOL(scsi_device_get); */ void scsi_device_put(struct scsi_device *sdev) { -#ifdef CONFIG_MODULE_UNLOAD - struct module *module = sdev->host->hostt->module; - - /* The module refcount will be zero if scsi_device_get() - * was called from a module removal routine */ - if (module && module_refcount(module) != 0) - module_put(module); -#endif + module_put(sdev->host->hostt->module); put_device(&sdev->sdev_gendev); } EXPORT_SYMBOL(scsi_device_put); |