aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2006-02-06 09:40:45 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-02-28 00:08:37 -0500
commit8cac814501677e9f6a824cf4d423122ac8d67fcb (patch)
tree60dfd19ceaf02739cbab9d9b42cb6b8e9c11e543 /drivers/scsi
parentfe27381d16c6683c55e618360d0d11bd43647e43 (diff)
[SCSI] aic7xxx: semaphore to completion conversion
On Tue, Jan 31, 2006 at 06:20:18PM +0100, Christoph Hellwig wrote: > switch eh_sem to a completion. due to wait_for_completion_timeout this > also nicely simplifies the code. Unfortunately it's untested, so if > someone with the hardware could give it a try that would be nice. Once > it works the same thing can be applied to aic79xx. New version that switches to the common onstack completion and just a pointer in the platform_data struct idiom. This gets rid of all the flags fiddling. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c45
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h5
2 files changed, 12 insertions, 38 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 051970efba68..2c801672d8bb 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -373,7 +373,6 @@ static void ahc_linux_handle_scsi_status(struct ahc_softc *,
373 struct scb *); 373 struct scb *);
374static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, 374static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
375 struct scsi_cmnd *cmd); 375 struct scsi_cmnd *cmd);
376static void ahc_linux_sem_timeout(u_long arg);
377static void ahc_linux_freeze_simq(struct ahc_softc *ahc); 376static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
378static void ahc_linux_release_simq(struct ahc_softc *ahc); 377static void ahc_linux_release_simq(struct ahc_softc *ahc);
379static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); 378static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
@@ -1193,7 +1192,6 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
1193 memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); 1192 memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
1194 ahc->platform_data->irq = AHC_LINUX_NOIRQ; 1193 ahc->platform_data->irq = AHC_LINUX_NOIRQ;
1195 ahc_lockinit(ahc); 1194 ahc_lockinit(ahc);
1196 init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
1197 ahc->seltime = (aic7xxx_seltime & 0x3) << 4; 1195 ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
1198 ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; 1196 ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
1199 if (aic7xxx_pci_parity == 0) 1197 if (aic7xxx_pci_parity == 0)
@@ -1830,10 +1828,9 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
1830 if (ahc_get_transaction_status(scb) == CAM_BDR_SENT 1828 if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
1831 || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED) 1829 || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
1832 ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT); 1830 ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
1833 if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) { 1831
1834 ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE; 1832 if (ahc->platform_data->eh_done)
1835 up(&ahc->platform_data->eh_sem); 1833 complete(ahc->platform_data->eh_done);
1836 }
1837 } 1834 }
1838 1835
1839 ahc_free_scb(ahc, scb); 1836 ahc_free_scb(ahc, scb);
@@ -2040,22 +2037,6 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
2040} 2037}
2041 2038
2042static void 2039static void
2043ahc_linux_sem_timeout(u_long arg)
2044{
2045 struct ahc_softc *ahc;
2046 u_long s;
2047
2048 ahc = (struct ahc_softc *)arg;
2049
2050 ahc_lock(ahc, &s);
2051 if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) {
2052 ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE;
2053 up(&ahc->platform_data->eh_sem);
2054 }
2055 ahc_unlock(ahc, &s);
2056}
2057
2058static void
2059ahc_linux_freeze_simq(struct ahc_softc *ahc) 2040ahc_linux_freeze_simq(struct ahc_softc *ahc)
2060{ 2041{
2061 unsigned long s; 2042 unsigned long s;
@@ -2355,25 +2336,21 @@ done:
2355 if (paused) 2336 if (paused)
2356 ahc_unpause(ahc); 2337 ahc_unpause(ahc);
2357 if (wait) { 2338 if (wait) {
2358 struct timer_list timer; 2339 DECLARE_COMPLETION(done);
2359 int ret;
2360 2340
2361 ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE; 2341 ahc->platform_data->eh_done = &done;
2362 ahc_unlock(ahc, &flags); 2342 ahc_unlock(ahc, &flags);
2363 2343
2364 init_timer(&timer);
2365 timer.data = (u_long)ahc;
2366 timer.expires = jiffies + (5 * HZ);
2367 timer.function = ahc_linux_sem_timeout;
2368 add_timer(&timer);
2369 printf("Recovery code sleeping\n"); 2344 printf("Recovery code sleeping\n");
2370 down(&ahc->platform_data->eh_sem); 2345 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
2371 printf("Recovery code awake\n"); 2346 ahc_lock(ahc, &flags);
2372 ret = del_timer_sync(&timer); 2347 ahc->platform_data->eh_done = NULL;
2373 if (ret == 0) { 2348 ahc_unlock(ahc, &flags);
2349
2374 printf("Timer Expired\n"); 2350 printf("Timer Expired\n");
2375 retval = FAILED; 2351 retval = FAILED;
2376 } 2352 }
2353 printf("Recovery code awake\n");
2377 } else 2354 } else
2378 ahc_unlock(ahc, &flags); 2355 ahc_unlock(ahc, &flags);
2379 return (retval); 2356 return (retval);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index e0edacae895f..a20b08c9ff15 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -369,15 +369,12 @@ struct ahc_platform_data {
369 369
370 spinlock_t spin_lock; 370 spinlock_t spin_lock;
371 u_int qfrozen; 371 u_int qfrozen;
372 struct semaphore eh_sem; 372 struct completion *eh_done;
373 struct Scsi_Host *host; /* pointer to scsi host */ 373 struct Scsi_Host *host; /* pointer to scsi host */
374#define AHC_LINUX_NOIRQ ((uint32_t)~0) 374#define AHC_LINUX_NOIRQ ((uint32_t)~0)
375 uint32_t irq; /* IRQ for this adapter */ 375 uint32_t irq; /* IRQ for this adapter */
376 uint32_t bios_address; 376 uint32_t bios_address;
377 uint32_t mem_busaddr; /* Mem Base Addr */ 377 uint32_t mem_busaddr; /* Mem Base Addr */
378
379#define AHC_UP_EH_SEMAPHORE 0x1
380 uint32_t flags;
381}; 378};
382 379
383/************************** OS Utility Wrappers *******************************/ 380/************************** OS Utility Wrappers *******************************/