[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>
This commit is contained in:
parent
fe27381d16
commit
8cac814501
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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 @@ done:
|
||||||
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 {
|
||||||
|
|
||||||
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 *******************************/
|
||||||
|
|
Loading…
Reference in New Issue