aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2005-05-17 01:06:08 -0400
committerJames Bottomley <jejb@titanic.(none)>2005-05-20 16:54:40 -0400
commit8e45ebcc661069bfb002c56dd942aedf43ba9239 (patch)
tree215c5b710ee6cbd55b0a51f9267486b9c263e67a /drivers/scsi
parent38c29ce06d24691d6e6dd786175fcc54efd5995b (diff)
[SCSI] aic7xxx: remove the completeq
This should finish the spurious queue removal from aic7xxx (there are other queues that are probably unnecessary, but at least the major and obviously unnecessary ones are done with). Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c121
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h17
2 files changed, 5 insertions, 133 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index d0c71da58e85..ca796b9d737b 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -433,7 +433,6 @@ static void ahc_linux_release_simq(u_long arg);
433static void ahc_linux_dev_timed_unfreeze(u_long arg); 433static void ahc_linux_dev_timed_unfreeze(u_long arg);
434static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); 434static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
435static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); 435static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
436static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc);
437static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, 436static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
438 struct ahc_devinfo *devinfo); 437 struct ahc_devinfo *devinfo);
439static void ahc_linux_device_queue_depth(struct ahc_softc *ahc, 438static void ahc_linux_device_queue_depth(struct ahc_softc *ahc,
@@ -454,29 +453,17 @@ static void ahc_linux_setup_tag_info_global(char *p);
454static aic_option_callback_t ahc_linux_setup_tag_info; 453static aic_option_callback_t ahc_linux_setup_tag_info;
455static int aic7xxx_setup(char *s); 454static int aic7xxx_setup(char *s);
456static int ahc_linux_next_unit(void); 455static int ahc_linux_next_unit(void);
457static struct ahc_cmd *ahc_linux_run_complete_queue(struct ahc_softc *ahc);
458 456
459/********************************* Inlines ************************************/ 457/********************************* Inlines ************************************/
460static __inline struct ahc_linux_device* 458static __inline struct ahc_linux_device*
461 ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, 459 ahc_linux_get_device(struct ahc_softc *ahc, u_int channel,
462 u_int target, u_int lun, int alloc); 460 u_int target, u_int lun, int alloc);
463static __inline void ahc_schedule_completeq(struct ahc_softc *ahc);
464static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); 461static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*);
465 462
466static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, 463static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
467 struct ahc_dma_seg *sg, 464 struct ahc_dma_seg *sg,
468 dma_addr_t addr, bus_size_t len); 465 dma_addr_t addr, bus_size_t len);
469 466
470static __inline void
471ahc_schedule_completeq(struct ahc_softc *ahc)
472{
473 if ((ahc->platform_data->flags & AHC_RUN_CMPLT_Q_TIMER) == 0) {
474 ahc->platform_data->flags |= AHC_RUN_CMPLT_Q_TIMER;
475 ahc->platform_data->completeq_timer.expires = jiffies;
476 add_timer(&ahc->platform_data->completeq_timer);
477 }
478}
479
480static __inline struct ahc_linux_device* 467static __inline struct ahc_linux_device*
481ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, 468ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target,
482 u_int lun, int alloc) 469 u_int lun, int alloc)
@@ -503,42 +490,6 @@ ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target,
503 return (dev); 490 return (dev);
504} 491}
505 492
506#define AHC_LINUX_MAX_RETURNED_ERRORS 4
507static struct ahc_cmd *
508ahc_linux_run_complete_queue(struct ahc_softc *ahc)
509{
510 struct ahc_cmd *acmd;
511 int with_errors;
512
513 with_errors = 0;
514 while ((acmd = TAILQ_FIRST(&ahc->platform_data->completeq)) != NULL) {
515 struct scsi_cmnd *cmd;
516
517 if (with_errors > AHC_LINUX_MAX_RETURNED_ERRORS) {
518 /*
519 * Linux uses stack recursion to requeue
520 * commands that need to be retried. Avoid
521 * blowing out the stack by "spoon feeding"
522 * commands that completed with error back
523 * the operating system in case they are going
524 * to be retried. "ick"
525 */
526 ahc_schedule_completeq(ahc);
527 break;
528 }
529 TAILQ_REMOVE(&ahc->platform_data->completeq,
530 acmd, acmd_links.tqe);
531 cmd = &acmd_scsi_cmd(acmd);
532 cmd->host_scribble = NULL;
533 if (ahc_cmd_get_transaction_status(cmd) != DID_OK
534 || (cmd->result & 0xFF) != SCSI_STATUS_OK)
535 with_errors++;
536
537 cmd->scsi_done(cmd);
538 }
539 return (acmd);
540}
541
542static __inline void 493static __inline void
543ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb) 494ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb)
544{ 495{
@@ -856,7 +807,6 @@ ahc_linux_bus_reset(struct scsi_cmnd *cmd)
856 ahc = *(struct ahc_softc **)cmd->device->host->hostdata; 807 ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
857 found = ahc_reset_channel(ahc, cmd->device->channel + 'A', 808 found = ahc_reset_channel(ahc, cmd->device->channel + 'A',
858 /*initiate reset*/TRUE); 809 /*initiate reset*/TRUE);
859 ahc_linux_run_complete_queue(ahc);
860 810
861 if (bootverbose) 811 if (bootverbose)
862 printf("%s: SCSI bus reset delivered. " 812 printf("%s: SCSI bus reset delivered. "
@@ -1331,13 +1281,8 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
1331 if (ahc->platform_data == NULL) 1281 if (ahc->platform_data == NULL)
1332 return (ENOMEM); 1282 return (ENOMEM);
1333 memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); 1283 memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
1334 TAILQ_INIT(&ahc->platform_data->completeq);
1335 ahc->platform_data->irq = AHC_LINUX_NOIRQ; 1284 ahc->platform_data->irq = AHC_LINUX_NOIRQ;
1336 ahc_lockinit(ahc); 1285 ahc_lockinit(ahc);
1337 init_timer(&ahc->platform_data->completeq_timer);
1338 ahc->platform_data->completeq_timer.data = (u_long)ahc;
1339 ahc->platform_data->completeq_timer.function =
1340 (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue;
1341 init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); 1286 init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
1342 ahc->seltime = (aic7xxx_seltime & 0x3) << 4; 1287 ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
1343 ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; 1288 ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
@@ -1355,7 +1300,6 @@ ahc_platform_free(struct ahc_softc *ahc)
1355 int i, j; 1300 int i, j;
1356 1301
1357 if (ahc->platform_data != NULL) { 1302 if (ahc->platform_data != NULL) {
1358 del_timer_sync(&ahc->platform_data->completeq_timer);
1359 if (ahc->platform_data->host != NULL) { 1303 if (ahc->platform_data->host != NULL) {
1360 scsi_remove_host(ahc->platform_data->host); 1304 scsi_remove_host(ahc->platform_data->host);
1361 scsi_host_put(ahc->platform_data->host); 1305 scsi_host_put(ahc->platform_data->host);
@@ -1504,18 +1448,6 @@ ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel,
1504 return 0; 1448 return 0;
1505} 1449}
1506 1450
1507static void
1508ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc)
1509{
1510 u_long flags;
1511
1512 ahc_lock(ahc, &flags);
1513 del_timer(&ahc->platform_data->completeq_timer);
1514 ahc->platform_data->flags &= ~AHC_RUN_CMPLT_Q_TIMER;
1515 ahc_linux_run_complete_queue(ahc);
1516 ahc_unlock(ahc, &flags);
1517}
1518
1519static u_int 1451static u_int
1520ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) 1452ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
1521{ 1453{
@@ -1785,7 +1717,6 @@ ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
1785 ahc = (struct ahc_softc *) dev_id; 1717 ahc = (struct ahc_softc *) dev_id;
1786 ahc_lock(ahc, &flags); 1718 ahc_lock(ahc, &flags);
1787 ours = ahc_intr(ahc); 1719 ours = ahc_intr(ahc);
1788 ahc_linux_run_complete_queue(ahc);
1789 ahc_unlock(ahc, &flags); 1720 ahc_unlock(ahc, &flags);
1790 return IRQ_RETVAL(ours); 1721 return IRQ_RETVAL(ours);
1791} 1722}
@@ -1794,8 +1725,6 @@ void
1794ahc_platform_flushwork(struct ahc_softc *ahc) 1725ahc_platform_flushwork(struct ahc_softc *ahc)
1795{ 1726{
1796 1727
1797 while (ahc_linux_run_complete_queue(ahc) != NULL)
1798 ;
1799} 1728}
1800 1729
1801static struct ahc_linux_target* 1730static struct ahc_linux_target*
@@ -2275,22 +2204,6 @@ static void
2275ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd) 2204ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
2276{ 2205{
2277 /* 2206 /*
2278 * Typically, the complete queue has very few entries
2279 * queued to it before the queue is emptied by
2280 * ahc_linux_run_complete_queue, so sorting the entries
2281 * by generation number should be inexpensive.
2282 * We perform the sort so that commands that complete
2283 * with an error are retuned in the order origionally
2284 * queued to the controller so that any subsequent retries
2285 * are performed in order. The underlying ahc routines do
2286 * not guarantee the order that aborted commands will be
2287 * returned to us.
2288 */
2289 struct ahc_completeq *completeq;
2290 struct ahc_cmd *list_cmd;
2291 struct ahc_cmd *acmd;
2292
2293 /*
2294 * Map CAM error codes into Linux Error codes. We 2207 * Map CAM error codes into Linux Error codes. We
2295 * avoid the conversion so that the DV code has the 2208 * avoid the conversion so that the DV code has the
2296 * full error information available when making 2209 * full error information available when making
@@ -2343,26 +2256,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
2343 new_status = DID_ERROR; 2256 new_status = DID_ERROR;
2344 break; 2257 break;
2345 case CAM_REQUEUE_REQ: 2258 case CAM_REQUEUE_REQ:
2346 /* 2259 new_status = DID_REQUEUE;
2347 * If we want the request requeued, make sure there
2348 * are sufficent retries. In the old scsi error code,
2349 * we used to be able to specify a result code that
2350 * bypassed the retry count. Now we must use this
2351 * hack. We also "fake" a check condition with
2352 * a sense code of ABORTED COMMAND. This seems to
2353 * evoke a retry even if this command is being sent
2354 * via the eh thread. Ick! Ick! Ick!
2355 */
2356 if (cmd->retries > 0)
2357 cmd->retries--;
2358 new_status = DID_OK;
2359 ahc_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);
2360 cmd->result |= (DRIVER_SENSE << 24);
2361 memset(cmd->sense_buffer, 0,
2362 sizeof(cmd->sense_buffer));
2363 cmd->sense_buffer[0] = SSD_ERRCODE_VALID
2364 | SSD_CURRENT_ERROR;
2365 cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND;
2366 break; 2260 break;
2367 default: 2261 default:
2368 /* We should never get here */ 2262 /* We should never get here */
@@ -2373,17 +2267,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
2373 ahc_cmd_set_transaction_status(cmd, new_status); 2267 ahc_cmd_set_transaction_status(cmd, new_status);
2374 } 2268 }
2375 2269
2376 completeq = &ahc->platform_data->completeq; 2270 cmd->scsi_done(cmd);
2377 list_cmd = TAILQ_FIRST(completeq);
2378 acmd = (struct ahc_cmd *)cmd;
2379 while (list_cmd != NULL
2380 && acmd_scsi_cmd(list_cmd).serial_number
2381 < acmd_scsi_cmd(acmd).serial_number)
2382 list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe);
2383 if (list_cmd != NULL)
2384 TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe);
2385 else
2386 TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe);
2387} 2271}
2388 2272
2389static void 2273static void
@@ -2747,7 +2631,6 @@ done:
2747 } 2631 }
2748 spin_lock_irq(&ahc->platform_data->spin_lock); 2632 spin_lock_irq(&ahc->platform_data->spin_lock);
2749 } 2633 }
2750 ahc_linux_run_complete_queue(ahc);
2751 return (retval); 2634 return (retval);
2752} 2635}
2753 2636
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 9ce7639dc739..e70c1fa47db2 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -436,16 +436,11 @@ struct ahc_linux_target {
436/* 436/*
437 * Per-SCB OSM storage. 437 * Per-SCB OSM storage.
438 */ 438 */
439typedef enum {
440 AHC_UP_EH_SEMAPHORE = 0x1
441} ahc_linux_scb_flags;
442
443struct scb_platform_data { 439struct scb_platform_data {
444 struct ahc_linux_device *dev; 440 struct ahc_linux_device *dev;
445 dma_addr_t buf_busaddr; 441 dma_addr_t buf_busaddr;
446 uint32_t xfer_len; 442 uint32_t xfer_len;
447 uint32_t sense_resid; /* Auto-Sense residual */ 443 uint32_t sense_resid; /* Auto-Sense residual */
448 ahc_linux_scb_flags flags;
449}; 444};
450 445
451/* 446/*
@@ -454,22 +449,14 @@ struct scb_platform_data {
454 * alignment restrictions of the various platforms supported by 449 * alignment restrictions of the various platforms supported by
455 * this driver. 450 * this driver.
456 */ 451 */
457typedef enum {
458 AHC_RUN_CMPLT_Q_TIMER = 0x10
459} ahc_linux_softc_flags;
460
461TAILQ_HEAD(ahc_completeq, ahc_cmd);
462
463struct ahc_platform_data { 452struct ahc_platform_data {
464 /* 453 /*
465 * Fields accessed from interrupt context. 454 * Fields accessed from interrupt context.
466 */ 455 */
467 struct ahc_linux_target *targets[AHC_NUM_TARGETS]; 456 struct ahc_linux_target *targets[AHC_NUM_TARGETS];
468 struct ahc_completeq completeq;
469 457
470 spinlock_t spin_lock; 458 spinlock_t spin_lock;
471 u_int qfrozen; 459 u_int qfrozen;
472 struct timer_list completeq_timer;
473 struct timer_list reset_timer; 460 struct timer_list reset_timer;
474 struct semaphore eh_sem; 461 struct semaphore eh_sem;
475 struct Scsi_Host *host; /* pointer to scsi host */ 462 struct Scsi_Host *host; /* pointer to scsi host */
@@ -477,7 +464,9 @@ struct ahc_platform_data {
477 uint32_t irq; /* IRQ for this adapter */ 464 uint32_t irq; /* IRQ for this adapter */
478 uint32_t bios_address; 465 uint32_t bios_address;
479 uint32_t mem_busaddr; /* Mem Base Addr */ 466 uint32_t mem_busaddr; /* Mem Base Addr */
480 ahc_linux_softc_flags flags; 467
468#define AHC_UP_EH_SEMAPHORE 0x1
469 uint32_t flags;
481}; 470};
482 471
483/************************** OS Utility Wrappers *******************************/ 472/************************** OS Utility Wrappers *******************************/