aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/advansys.c
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew@wil.cx>2007-09-09 10:56:31 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:47:44 -0400
commitb66229258f88a06ecdb8998066861b3ad8ad6a2a (patch)
tree04bccc41fe172c9035b9e0d7bf1804b5d2865eb2 /drivers/scsi/advansys.c
parentc2dce2fabc7f0b559e920890d13e7b8ecfc91e13 (diff)
[SCSI] advansys: Remove `waiting' queue
If the adapter is busy, return the request to the midlayer rather than queueing it in the driver. asc_execute_queue() and asc_dequeue() become unused, and we don't need to print out stats on the waiting queue any more. Signed-off-by: Matthew Wilcox <matthew@wil.cx> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/advansys.c')
-rw-r--r--drivers/scsi/advansys.c186
1 files changed, 9 insertions, 177 deletions
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index fe289b1d7ddb..526239a21332 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -2852,7 +2852,6 @@ typedef struct asc_board {
2852 } dvc_cfg; 2852 } dvc_cfg;
2853 ushort asc_n_io_port; /* Number I/O ports. */ 2853 ushort asc_n_io_port; /* Number I/O ports. */
2854 asc_queue_t active; /* Active command queue */ 2854 asc_queue_t active; /* Active command queue */
2855 asc_queue_t waiting; /* Waiting command queue */
2856 asc_queue_t done; /* Done command queue */ 2855 asc_queue_t done; /* Done command queue */
2857 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */ 2856 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
2858 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */ 2857 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
@@ -2922,10 +2921,8 @@ static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
2922static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **); 2921static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
2923static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int); 2922static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
2924static void asc_enqueue(asc_queue_t *, REQP, int); 2923static void asc_enqueue(asc_queue_t *, REQP, int);
2925static REQP asc_dequeue(asc_queue_t *, int);
2926static REQP asc_dequeue_list(asc_queue_t *, REQP *, int); 2924static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
2927static int asc_rmqueue(asc_queue_t *, REQP); 2925static int asc_rmqueue(asc_queue_t *, REQP);
2928static void asc_execute_queue(asc_queue_t *);
2929#ifdef CONFIG_PROC_FS 2926#ifdef CONFIG_PROC_FS
2930static int asc_proc_copy(off_t, off_t, char *, int, char *, int); 2927static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
2931static int asc_prt_board_devices(struct Scsi_Host *, char *, int); 2928static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
@@ -3274,6 +3271,7 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
3274 asc_board_t *boardp; 3271 asc_board_t *boardp;
3275 ulong flags; 3272 ulong flags;
3276 struct scsi_cmnd *done_scp; 3273 struct scsi_cmnd *done_scp;
3274 int asc_res, result = 0;
3277 3275
3278 shost = scp->device->host; 3276 shost = scp->device->host;
3279 boardp = ASC_BOARDP(shost); 3277 boardp = ASC_BOARDP(shost);
@@ -3302,37 +3300,13 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
3302 return 0; 3300 return 0;
3303 } 3301 }
3304 3302
3305 /*
3306 * Attempt to execute any waiting commands for the board.
3307 */
3308 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
3309 ASC_DBG(1,
3310 "advansys_queuecommand: before asc_execute_queue() waiting\n");
3311 asc_execute_queue(&boardp->waiting);
3312 }
3313
3314 /*
3315 * Save the function pointer to Linux mid-level 'done' function
3316 * and attempt to execute the command.
3317 *
3318 * If ASC_NOERROR is returned the request has been added to the
3319 * board's 'active' queue and will be completed by the interrupt
3320 * handler.
3321 *
3322 * If ASC_BUSY is returned add the request to the board's per
3323 * target waiting list. This is the first time the request has
3324 * been tried. Add it to the back of the waiting list. It will be
3325 * retried later.
3326 *
3327 * If an error occurred, the request will have been placed on the
3328 * board's 'done' queue and must be completed before returning.
3329 */
3330 scp->scsi_done = done; 3303 scp->scsi_done = done;
3331 switch (asc_execute_scsi_cmnd(scp)) { 3304 asc_res = asc_execute_scsi_cmnd(scp);
3305 switch (asc_res) {
3332 case ASC_NOERROR: 3306 case ASC_NOERROR:
3333 break; 3307 break;
3334 case ASC_BUSY: 3308 case ASC_BUSY:
3335 asc_enqueue(&boardp->waiting, scp, ASC_BACK); 3309 result = SCSI_MLQUEUE_HOST_BUSY;
3336 break; 3310 break;
3337 case ASC_ERROR: 3311 case ASC_ERROR:
3338 default: 3312 default:
@@ -3343,7 +3317,7 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
3343 } 3317 }
3344 spin_unlock_irqrestore(&boardp->lock, flags); 3318 spin_unlock_irqrestore(&boardp->lock, flags);
3345 3319
3346 return 0; 3320 return result;
3347} 3321}
3348 3322
3349/* 3323/*
@@ -3488,33 +3462,6 @@ static int advansys_reset(struct scsi_cmnd *scp)
3488 } 3462 }
3489 } 3463 }
3490 3464
3491 /*
3492 * Dequeue all 'waiting' requests and set the request status
3493 * to DID_RESET.
3494 */
3495 if (done_scp == NULL) {
3496 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp,
3497 ASC_TID_ALL);
3498 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
3499 tscp->result = HOST_BYTE(DID_RESET);
3500 }
3501 } else {
3502 /* Append to 'done_scp' at the end with 'last_scp'. */
3503 ASC_ASSERT(last_scp != NULL);
3504 last_scp->host_scribble =
3505 (unsigned char *)asc_dequeue_list(&boardp->waiting,
3506 &new_last_scp,
3507 ASC_TID_ALL);
3508 if (new_last_scp != NULL) {
3509 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
3510 for (tscp = REQPNEXT(last_scp); tscp;
3511 tscp = REQPNEXT(tscp)) {
3512 tscp->result = HOST_BYTE(DID_RESET);
3513 }
3514 last_scp = new_last_scp;
3515 }
3516 }
3517
3518 /* Save the time of the most recently completed reset. */ 3465 /* Save the time of the most recently completed reset. */
3519 boardp->last_reset = jiffies; 3466 boardp->last_reset = jiffies;
3520 3467
@@ -3650,7 +3597,7 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id)
3650 } 3597 }
3651 3598
3652 /* 3599 /*
3653 * Start waiting requests and create a list of completed requests. 3600 * Create a list of completed requests.
3654 * 3601 *
3655 * If a reset request is being performed for the board, the reset 3602 * If a reset request is being performed for the board, the reset
3656 * handler will complete pending requests after it has completed. 3603 * handler will complete pending requests after it has completed.
@@ -3659,13 +3606,6 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id)
3659 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, " 3606 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
3660 "last_scp 0x%p\n", done_scp, last_scp); 3607 "last_scp 0x%p\n", done_scp, last_scp);
3661 3608
3662 /* Start any waiting commands for the board. */
3663 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
3664 ASC_DBG(1, "advansys_interrupt: before "
3665 "asc_execute_queue()\n");
3666 asc_execute_queue(&boardp->waiting);
3667 }
3668
3669 /* 3609 /*
3670 * Add to the list of requests that must be completed. 3610 * Add to the list of requests that must be completed.
3671 * 3611 *
@@ -3986,8 +3926,8 @@ static void asc_scsi_done_list(struct scsi_cmnd *scp)
3986 * If this function returns ASC_NOERROR the request has been enqueued 3926 * If this function returns ASC_NOERROR the request has been enqueued
3987 * on the board's 'done' queue and must be completed by the caller. 3927 * on the board's 'done' queue and must be completed by the caller.
3988 * 3928 *
3989 * If ASC_BUSY is returned the request will be enqueued by the 3929 * If ASC_BUSY is returned the request will be returned to the midlayer
3990 * caller on the target's waiting queue and re-tried later. 3930 * and re-tried later.
3991 */ 3931 */
3992static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) 3932static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
3993{ 3933{
@@ -4043,10 +3983,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4043 "ASC_NOERROR\n"); 3983 "ASC_NOERROR\n");
4044 break; 3984 break;
4045 case ASC_BUSY: 3985 case ASC_BUSY:
4046 /*
4047 * Caller will enqueue request on the target's waiting
4048 * queue and retry later.
4049 */
4050 ASC_STATS(scp->device->host, exe_busy); 3986 ASC_STATS(scp->device->host, exe_busy);
4051 break; 3987 break;
4052 case ASC_ERROR: 3988 case ASC_ERROR:
@@ -4087,10 +4023,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4087 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " 4023 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4088 "ASC_BUSY\n"); 4024 "ASC_BUSY\n");
4089 /* 4025 /*
4090 * If busy is returned the request has not been
4091 * enqueued. It will be enqueued by the caller on the
4092 * target's waiting queue and retried later.
4093 *
4094 * The asc_stats fields 'adv_build_noreq' and 4026 * The asc_stats fields 'adv_build_noreq' and
4095 * 'adv_build_nosg' count wide board busy conditions. 4027 * 'adv_build_nosg' count wide board busy conditions.
4096 * They are updated in adv_build_req and 4028 * They are updated in adv_build_req and
@@ -4127,10 +4059,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4127 "ASC_NOERROR\n"); 4059 "ASC_NOERROR\n");
4128 break; 4060 break;
4129 case ASC_BUSY: 4061 case ASC_BUSY:
4130 /*
4131 * Caller will enqueue request on the target's waiting
4132 * queue and retry later.
4133 */
4134 ASC_STATS(scp->device->host, exe_busy); 4062 ASC_STATS(scp->device->host, exe_busy);
4135 break; 4063 break;
4136 case ASC_ERROR: 4064 case ASC_ERROR:
@@ -5005,39 +4933,6 @@ static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
5005} 4933}
5006 4934
5007/* 4935/*
5008 * Return first queued 'REQP' on the specified queue for
5009 * the specified target device. Clear the 'tidmask' bit for
5010 * the device if no more commands are left queued for it.
5011 *
5012 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5013 */
5014static REQP asc_dequeue(asc_queue_t *ascq, int tid)
5015{
5016 REQP reqp;
5017
5018 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5019 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5020 if ((reqp = ascq->q_first[tid]) != NULL) {
5021 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5022 ascq->q_first[tid] = REQPNEXT(reqp);
5023 /* If the queue is empty, clear its bit and the last pointer. */
5024 if (ascq->q_first[tid] == NULL) {
5025 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5026 ASC_ASSERT(ascq->q_last[tid] == reqp);
5027 ascq->q_last[tid] = NULL;
5028 }
5029#ifdef ADVANSYS_STATS
5030 /* Maintain request queue statistics. */
5031 ascq->q_cur_cnt[tid]--;
5032 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5033 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
5034#endif /* ADVANSYS_STATS */
5035 }
5036 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5037 return reqp;
5038}
5039
5040/*
5041 * Return a pointer to a singly linked list of all the requests queued 4936 * Return a pointer to a singly linked list of all the requests queued
5042 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'. 4937 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5043 * 4938 *
@@ -5202,45 +5097,6 @@ static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
5202 return ret; 5097 return ret;
5203} 5098}
5204 5099
5205/*
5206 * Execute as many queued requests as possible for the specified queue.
5207 *
5208 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
5209 */
5210static void asc_execute_queue(asc_queue_t *ascq)
5211{
5212 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
5213 REQP reqp;
5214 int i;
5215
5216 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
5217 /*
5218 * Execute queued commands for devices attached to
5219 * the current board in round-robin fashion.
5220 */
5221 scan_tidmask = ascq->q_tidmask;
5222 do {
5223 for (i = 0; i <= ADV_MAX_TID; i++) {
5224 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
5225 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
5226 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5227 } else
5228 if (asc_execute_scsi_cmnd
5229 ((struct scsi_cmnd *)reqp)
5230 == ASC_BUSY) {
5231 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5232 /*
5233 * The request returned ASC_BUSY. Enqueue at the front of
5234 * target's waiting list to maintain correct ordering.
5235 */
5236 asc_enqueue(ascq, reqp, ASC_FRONT);
5237 }
5238 }
5239 }
5240 } while (scan_tidmask);
5241 return;
5242}
5243
5244#ifdef CONFIG_PROC_FS 5100#ifdef CONFIG_PROC_FS
5245/* 5101/*
5246 * asc_prt_board_devices() 5102 * asc_prt_board_devices()
@@ -6723,7 +6579,6 @@ asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
6723 ushort chip_scsi_id; 6579 ushort chip_scsi_id;
6724 asc_board_t *boardp; 6580 asc_board_t *boardp;
6725 asc_queue_t *active; 6581 asc_queue_t *active;
6726 asc_queue_t *waiting;
6727 6582
6728 leftlen = cplen; 6583 leftlen = cplen;
6729 totlen = len = 0; 6584 totlen = len = 0;
@@ -6732,7 +6587,6 @@ asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
6732 s = &boardp->asc_stats; 6587 s = &boardp->asc_stats;
6733 6588
6734 active = &ASC_BOARDP(shost)->active; 6589 active = &ASC_BOARDP(shost)->active;
6735 waiting = &ASC_BOARDP(shost)->waiting;
6736 6590
6737 if (ASC_NARROW_BOARD(boardp)) { 6591 if (ASC_NARROW_BOARD(boardp)) {
6738 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; 6592 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
@@ -6746,8 +6600,7 @@ asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
6746 } 6600 }
6747 6601
6748 do { 6602 do {
6749 if (active->q_tot_cnt[tgt_id] > 0 6603 if (active->q_tot_cnt[tgt_id] > 0) {
6750 || waiting->q_tot_cnt[tgt_id] > 0) {
6751 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id); 6604 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
6752 ASC_PRT_NEXT(); 6605 ASC_PRT_NEXT();
6753 6606
@@ -6771,27 +6624,6 @@ asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
6771 q_tot_cnt 6624 q_tot_cnt
6772 [tgt_id])); 6625 [tgt_id]));
6773 ASC_PRT_NEXT(); 6626 ASC_PRT_NEXT();
6774
6775 len = asc_prt_line(cp, leftlen,
6776 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
6777 waiting->q_cur_cnt[tgt_id],
6778 waiting->q_max_cnt[tgt_id],
6779 waiting->q_tot_cnt[tgt_id],
6780 waiting->q_min_tim[tgt_id],
6781 waiting->q_max_tim[tgt_id],
6782 (waiting->q_tot_cnt[tgt_id] ==
6783 0) ? 0 : (waiting->
6784 q_tot_tim[tgt_id] /
6785 waiting->
6786 q_tot_cnt[tgt_id]),
6787 (waiting->q_tot_cnt[tgt_id] ==
6788 0) ? 0 : ASC_TENTHS(waiting->
6789 q_tot_tim
6790 [tgt_id],
6791 waiting->
6792 q_tot_cnt
6793 [tgt_id]));
6794 ASC_PRT_NEXT();
6795 } 6627 }
6796 } while (0); 6628 } while (0);
6797 6629