|
@@ -1233,6 +1233,50 @@ static inline void complete_buffers(struct bio *bio, int status)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void cciss_check_queues(ctlr_info_t *h)
|
|
|
+{
|
|
|
+ int start_queue = h->next_to_run;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* check to see if we have maxed out the number of commands that can
|
|
|
+ * be placed on the queue. If so then exit. We do this check here
|
|
|
+ * in case the interrupt we serviced was from an ioctl and did not
|
|
|
+ * free any new commands.
|
|
|
+ */
|
|
|
+ if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* We have room on the queue for more commands. Now we need to queue
|
|
|
+ * them up. We will also keep track of the next queue to run so
|
|
|
+ * that every queue gets a chance to be started first.
|
|
|
+ */
|
|
|
+ for (i = 0; i < h->highest_lun + 1; i++) {
|
|
|
+ int curr_queue = (start_queue + i) % (h->highest_lun + 1);
|
|
|
+ /* make sure the disk has been added and the drive is real
|
|
|
+ * because this can be called from the middle of init_one.
|
|
|
+ */
|
|
|
+ if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads))
|
|
|
+ continue;
|
|
|
+ blk_start_queue(h->gendisk[curr_queue]->queue);
|
|
|
+
|
|
|
+ /* check to see if we have maxed out the number of commands
|
|
|
+ * that can be placed on the queue.
|
|
|
+ */
|
|
|
+ if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) {
|
|
|
+ if (curr_queue == start_queue) {
|
|
|
+ h->next_to_run =
|
|
|
+ (start_queue + 1) % (h->highest_lun + 1);
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ h->next_to_run = curr_queue;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ curr_queue = (curr_queue + 1) % (h->highest_lun + 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void cciss_softirq_done(struct request *rq)
|
|
|
{
|
|
|
CommandList_struct *cmd = rq->completion_data;
|
|
@@ -1264,6 +1308,7 @@ static void cciss_softirq_done(struct request *rq)
|
|
|
spin_lock_irqsave(&h->lock, flags);
|
|
|
end_that_request_last(rq, rq->errors);
|
|
|
cmd_free(h, cmd, 1);
|
|
|
+ cciss_check_queues(h);
|
|
|
spin_unlock_irqrestore(&h->lock, flags);
|
|
|
}
|
|
|
|
|
@@ -2528,8 +2573,6 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
|
|
|
CommandList_struct *c;
|
|
|
unsigned long flags;
|
|
|
__u32 a, a1, a2;
|
|
|
- int j;
|
|
|
- int start_queue = h->next_to_run;
|
|
|
|
|
|
if (interrupt_not_for_us(h))
|
|
|
return IRQ_NONE;
|
|
@@ -2588,45 +2631,6 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /* check to see if we have maxed out the number of commands that can
|
|
|
- * be placed on the queue. If so then exit. We do this check here
|
|
|
- * in case the interrupt we serviced was from an ioctl and did not
|
|
|
- * free any new commands.
|
|
|
- */
|
|
|
- if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
|
|
|
- goto cleanup;
|
|
|
-
|
|
|
- /* We have room on the queue for more commands. Now we need to queue
|
|
|
- * them up. We will also keep track of the next queue to run so
|
|
|
- * that every queue gets a chance to be started first.
|
|
|
- */
|
|
|
- for (j = 0; j < h->highest_lun + 1; j++) {
|
|
|
- int curr_queue = (start_queue + j) % (h->highest_lun + 1);
|
|
|
- /* make sure the disk has been added and the drive is real
|
|
|
- * because this can be called from the middle of init_one.
|
|
|
- */
|
|
|
- if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads))
|
|
|
- continue;
|
|
|
- blk_start_queue(h->gendisk[curr_queue]->queue);
|
|
|
-
|
|
|
- /* check to see if we have maxed out the number of commands
|
|
|
- * that can be placed on the queue.
|
|
|
- */
|
|
|
- if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) {
|
|
|
- if (curr_queue == start_queue) {
|
|
|
- h->next_to_run =
|
|
|
- (start_queue + 1) % (h->highest_lun + 1);
|
|
|
- goto cleanup;
|
|
|
- } else {
|
|
|
- h->next_to_run = curr_queue;
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- } else {
|
|
|
- curr_queue = (curr_queue + 1) % (h->highest_lun + 1);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- cleanup:
|
|
|
spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
|
|
|
return IRQ_HANDLED;
|
|
|
}
|