Commit 8cac8145 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley

[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: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent fe27381d
...@@ -373,7 +373,6 @@ static void ahc_linux_handle_scsi_status(struct ahc_softc *, ...@@ -373,7 +373,6 @@ static void ahc_linux_handle_scsi_status(struct ahc_softc *,
struct scb *); struct scb *);
static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
struct scsi_cmnd *cmd); struct scsi_cmnd *cmd);
static void ahc_linux_sem_timeout(u_long arg);
static void ahc_linux_freeze_simq(struct ahc_softc *ahc); static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
static void ahc_linux_release_simq(struct ahc_softc *ahc); static void ahc_linux_release_simq(struct ahc_softc *ahc);
static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); static 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,7 +1192,6 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
ahc->platform_data->irq = AHC_LINUX_NOIRQ; ahc->platform_data->irq = AHC_LINUX_NOIRQ;
ahc_lockinit(ahc); ahc_lockinit(ahc);
init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
ahc->seltime = (aic7xxx_seltime & 0x3) << 4; ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
if (aic7xxx_pci_parity == 0) if (aic7xxx_pci_parity == 0)
...@@ -1830,10 +1828,9 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) ...@@ -1830,10 +1828,9 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
if (ahc_get_transaction_status(scb) == CAM_BDR_SENT if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
|| ahc_get_transaction_status(scb) == CAM_REQ_ABORTED) || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT); ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) {
ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE; if (ahc->platform_data->eh_done)
up(&ahc->platform_data->eh_sem); complete(ahc->platform_data->eh_done);
}
} }
ahc_free_scb(ahc, scb); ahc_free_scb(ahc, scb);
...@@ -2039,22 +2036,6 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd) ...@@ -2039,22 +2036,6 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
} }
static void
ahc_linux_sem_timeout(u_long arg)
{
struct ahc_softc *ahc;
u_long s;
ahc = (struct ahc_softc *)arg;
ahc_lock(ahc, &s);
if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) {
ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE;
up(&ahc->platform_data->eh_sem);
}
ahc_unlock(ahc, &s);
}
static void static void
ahc_linux_freeze_simq(struct ahc_softc *ahc) ahc_linux_freeze_simq(struct ahc_softc *ahc)
{ {
...@@ -2355,25 +2336,21 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) ...@@ -2355,25 +2336,21 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
if (paused) if (paused)
ahc_unpause(ahc); ahc_unpause(ahc);
if (wait) { if (wait) {
struct timer_list timer; DECLARE_COMPLETION(done);
int ret;
ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE; ahc->platform_data->eh_done = &done;
ahc_unlock(ahc, &flags); ahc_unlock(ahc, &flags);
init_timer(&timer);
timer.data = (u_long)ahc;
timer.expires = jiffies + (5 * HZ);
timer.function = ahc_linux_sem_timeout;
add_timer(&timer);
printf("Recovery code sleeping\n"); printf("Recovery code sleeping\n");
down(&ahc->platform_data->eh_sem); if (!wait_for_completion_timeout(&done, 5 * HZ)) {
printf("Recovery code awake\n"); ahc_lock(ahc, &flags);
ret = del_timer_sync(&timer); ahc->platform_data->eh_done = NULL;
if (ret == 0) { ahc_unlock(ahc, &flags);
printf("Timer Expired\n"); printf("Timer Expired\n");
retval = FAILED; retval = FAILED;
} }
printf("Recovery code awake\n");
} else } else
ahc_unlock(ahc, &flags); ahc_unlock(ahc, &flags);
return (retval); return (retval);
......
...@@ -369,15 +369,12 @@ struct ahc_platform_data { ...@@ -369,15 +369,12 @@ struct ahc_platform_data {
spinlock_t spin_lock; spinlock_t spin_lock;
u_int qfrozen; u_int qfrozen;
struct semaphore eh_sem; struct completion *eh_done;
struct Scsi_Host *host; /* pointer to scsi host */ struct Scsi_Host *host; /* pointer to scsi host */
#define AHC_LINUX_NOIRQ ((uint32_t)~0) #define AHC_LINUX_NOIRQ ((uint32_t)~0)
uint32_t irq; /* IRQ for this adapter */ uint32_t irq; /* IRQ for this adapter */
uint32_t bios_address; uint32_t bios_address;
uint32_t mem_busaddr; /* Mem Base Addr */ uint32_t mem_busaddr; /* Mem Base Addr */
#define AHC_UP_EH_SEMAPHORE 0x1
uint32_t flags;
}; };
/************************** OS Utility Wrappers *******************************/ /************************** OS Utility Wrappers *******************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment