scsi_queue.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  scsi_queue.c Copyright (C) 1997 Eric Youngdale
  3.  *
  4.  *  generic mid-level SCSI queueing.
  5.  *
  6.  *  The point of this is that we need to track when hosts are unable to
  7.  *  accept a command because they are busy.  In addition, we track devices
  8.  *  that cannot accept a command because of a QUEUE_FULL condition.  In both
  9.  *  of these cases, we enter the command in the queue.  At some later point,
  10.  *  we attempt to remove commands from the queue and retry them.
  11.  */
  12. #define __NO_VERSION__
  13. #include <linux/module.h>
  14. #include <linux/sched.h>
  15. #include <linux/timer.h>
  16. #include <linux/string.h>
  17. #include <linux/slab.h>
  18. #include <linux/ioport.h>
  19. #include <linux/kernel.h>
  20. #include <linux/stat.h>
  21. #include <linux/blk.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/delay.h>
  24. #include <linux/smp_lock.h>
  25. #define __KERNEL_SYSCALLS__
  26. #include <linux/unistd.h>
  27. #include <asm/system.h>
  28. #include <asm/irq.h>
  29. #include <asm/dma.h>
  30. #include "scsi.h"
  31. #include "hosts.h"
  32. #include "constants.h"
  33. /*
  34.  * TODO:
  35.  *      1) Prevent multiple traversals of list to look for commands to
  36.  *         queue.
  37.  *      2) Protect against multiple insertions of list at the same time.
  38.  * DONE:
  39.  *      1) Set state of scsi command to a new state value for ml queue.
  40.  *      2) Insert into queue when host rejects command.
  41.  *      3) Make sure status code is properly passed from low-level queue func
  42.  *         so that internal_cmnd properly returns the right value.
  43.  *      4) Insert into queue when QUEUE_FULL.
  44.  *      5) Cull queue in bottom half handler.
  45.  *      6) Check usage count prior to queue insertion.  Requeue if usage
  46.  *         count is 0.
  47.  *      7) Don't send down any more commands if the host/device is busy.
  48.  */
  49. static const char RCSid[] = "$Header: /mnt/ide/home/eric/CVSROOT/linux/drivers/scsi/scsi_queue.c,v 1.1 1997/10/21 11:16:38 eric Exp $";
  50. /*
  51.  * Function:    scsi_mlqueue_insert()
  52.  *
  53.  * Purpose:     Insert a command in the midlevel queue.
  54.  *
  55.  * Arguments:   cmd    - command that we are adding to queue.
  56.  *              reason - why we are inserting command to queue.
  57.  *
  58.  * Lock status: Assumed that lock is not held upon entry.
  59.  *
  60.  * Returns:     Nothing.
  61.  *
  62.  * Notes:       We do this for one of two cases.  Either the host is busy
  63.  *              and it cannot accept any more commands for the time being,
  64.  *              or the device returned QUEUE_FULL and can accept no more
  65.  *              commands.
  66.  * Notes:       This could be called either from an interrupt context or a
  67.  *              normal process context.
  68.  */
  69. int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason)
  70. {
  71. struct Scsi_Host *host;
  72. unsigned long flags;
  73. SCSI_LOG_MLQUEUE(1, printk("Inserting command %p into mlqueuen", cmd));
  74. /*
  75.  * We are inserting the command into the ml queue.  First, we
  76.  * cancel the timer, so it doesn't time out.
  77.  */
  78. scsi_delete_timer(cmd);
  79. host = cmd->host;
  80. /*
  81.  * Next, set the appropriate busy bit for the device/host.
  82.  */
  83. if (reason == SCSI_MLQUEUE_HOST_BUSY) {
  84. /*
  85.  * Protect against race conditions.  If the host isn't busy,
  86.  * assume that something actually completed, and that we should
  87.  * be able to queue a command now.  Note that there is an implicit
  88.  * assumption that every host can always queue at least one command.
  89.  * If a host is inactive and cannot queue any commands, I don't see
  90.  * how things could possibly work anyways.
  91.  */
  92. if (host->host_busy == 0) {
  93. if (scsi_retry_command(cmd) == 0) {
  94. return 0;
  95. }
  96. }
  97. host->host_blocked = TRUE;
  98. } else {
  99. /*
  100.  * Protect against race conditions.  If the device isn't busy,
  101.  * assume that something actually completed, and that we should
  102.  * be able to queue a command now.  Note that there is an implicit
  103.  * assumption that every host can always queue at least one command.
  104.  * If a host is inactive and cannot queue any commands, I don't see
  105.  * how things could possibly work anyways.
  106.  */
  107. if (cmd->device->device_busy == 0) {
  108. if (scsi_retry_command(cmd) == 0) {
  109. return 0;
  110. }
  111. }
  112. cmd->device->device_blocked = TRUE;
  113. }
  114. /*
  115.  * Register the fact that we own the thing for now.
  116.  */
  117. cmd->state = SCSI_STATE_MLQUEUE;
  118. cmd->owner = SCSI_OWNER_MIDLEVEL;
  119. cmd->bh_next = NULL;
  120. /*
  121.  * Decrement the counters, since these commands are no longer
  122.  * active on the host/device.
  123.  */
  124. spin_lock_irqsave(&io_request_lock, flags);
  125. cmd->host->host_busy--;
  126. cmd->device->device_busy--;
  127. spin_unlock_irqrestore(&io_request_lock, flags);
  128. /*
  129.  * Insert this command at the head of the queue for it's device.
  130.  * It will go before all other commands that are already in the queue.
  131.  */
  132. scsi_insert_special_cmd(cmd, 1);
  133. return 0;
  134. }