Commit 4e665bdd authored by James Bottomley's avatar James Bottomley

fix NC5380 locking and delayed work handling

From: Christoph Hellwig <hch@lst.de>

 - move delayed workqueue handling to schedule_delayed_work instead
   of the old horrible global list thing
 - add NCR5380_exit to make sure all delayed work is flushed on HBA
   (or module) removal
 - fix locking

Patch fixed up to apply and
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 8651e2bd
This diff is collapsed.
......@@ -251,7 +251,6 @@
struct NCR5380_hostdata {
NCR5380_implementation_fields; /* implementation specific */
struct Scsi_Host *host; /* Host backpointer */
struct NCR5380_hostdata *next; /* Next in our hot chain */
unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */
unsigned char targets_present; /* targets we have connected
to, so we can call a select
......@@ -270,7 +269,6 @@ struct NCR5380_hostdata {
volatile unsigned aborted:1; /* flag, says aborted */
int flags;
unsigned long time_expires; /* in jiffies, set prior to sleeping */
struct Scsi_Host *next_timer;
int select_time; /* timer in select for target response */
volatile Scsi_Cmnd *selecting;
struct work_struct coroutine; /* our co-routine */
......@@ -295,6 +293,7 @@ struct NCR5380_hostdata {
static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
#endif
static int NCR5380_init(struct Scsi_Host *instance, int flags);
static void NCR5380_exit(struct Scsi_Host *instance);
static void NCR5380_information_transfer(struct Scsi_Host *instance);
#ifndef DONT_USE_INTR
static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs);
......
......@@ -321,6 +321,7 @@ static void __devexit cumanascsi1_remove(struct expansion_card *ec)
scsi_remove_host(host);
free_irq(host->irq, host);
NCR5380_exit(host);
release_region(host->io_port, host->n_io_port);
scsi_host_put(host);
}
......
......@@ -222,6 +222,7 @@ static void __exit ecoscsi_exit(void)
if (shpnt->irq != IRQ_NONE)
free_irq(shpnt->irq, NULL);
NCR5380_exit(host);
if (shpnt->io_port)
release_region(shpnt->io_port, shpnt->n_io_port);
......
......@@ -179,6 +179,7 @@ static void __devexit oakscsi_remove(struct expansion_card *ec)
ecard_set_drvdata(ec, NULL);
scsi_remove_host(host);
NCR5380_exit(host);
release_region(host->io_port, host->n_io_port);
scsi_host_put(host);
}
......
......@@ -106,9 +106,10 @@ static const char * dmx3191d_info(struct Scsi_Host *host) {
static int dmx3191d_release_resources(struct Scsi_Host *instance)
{
release_region(instance->io_port, DMX3191D_REGION);
if(instance->irq!=SCSI_IRQ_NONE)
free_irq(instance->irq, instance);
NCR5380_exit(instance);
release_region(instance->io_port, DMX3191D_REGION);
return 0;
}
......
......@@ -451,6 +451,7 @@ static int dtc_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
NCR5380_exit(shost);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
......
......@@ -501,6 +501,10 @@ int generic_NCR5380_release_resources(struct Scsi_Host *instance)
{
NCR5380_local_declare();
NCR5380_setup(instance);
if (instance->irq != SCSI_IRQ_NONE)
free_irq(instance->irq, NULL);
NCR5380_exit(instance);
#ifndef CONFIG_SCSI_G_NCR5380_MEM
release_region(instance->NCR5380_instance_name, instance->n_io_port);
......@@ -508,8 +512,6 @@ int generic_NCR5380_release_resources(struct Scsi_Host *instance)
release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size);
#endif
if (instance->irq != SCSI_IRQ_NONE)
free_irq(instance->irq, NULL);
return 0;
}
......
......@@ -326,6 +326,7 @@ int macscsi_release (struct Scsi_Host *shpnt)
{
if (shpnt->irq != SCSI_IRQ_NONE)
free_irq (shpnt->irq, NCR5380_intr);
NCR5380_exit(shpnt);
return 0;
}
......
......@@ -605,6 +605,7 @@ static int pas16_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
NCR5380_exit(shost);
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
......
......@@ -284,6 +284,7 @@ static int t128_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
NCR5380_exit(shost);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
......
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