diff options
| -rw-r--r-- | drivers/scsi/a2091.c | 75 |
1 files changed, 41 insertions, 34 deletions
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index fc4fce99528e..1bb5d3f0e260 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c | |||
| @@ -16,11 +16,16 @@ | |||
| 16 | #include "a2091.h" | 16 | #include "a2091.h" |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | struct a2091_hostdata { | ||
| 20 | struct WD33C93_hostdata wh; | ||
| 21 | struct a2091_scsiregs *regs; | ||
| 22 | }; | ||
| 23 | |||
| 19 | static irqreturn_t a2091_intr(int irq, void *data) | 24 | static irqreturn_t a2091_intr(int irq, void *data) |
| 20 | { | 25 | { |
| 21 | struct Scsi_Host *instance = data; | 26 | struct Scsi_Host *instance = data; |
| 22 | struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); | 27 | struct a2091_hostdata *hdata = shost_priv(instance); |
| 23 | unsigned int status = regs->ISTR; | 28 | unsigned int status = hdata->regs->ISTR; |
| 24 | unsigned long flags; | 29 | unsigned long flags; |
| 25 | 30 | ||
| 26 | if (!(status & (ISTR_INT_F | ISTR_INT_P)) || !(status & ISTR_INTS)) | 31 | if (!(status & (ISTR_INT_F | ISTR_INT_P)) || !(status & ISTR_INTS)) |
| @@ -35,38 +40,39 @@ static irqreturn_t a2091_intr(int irq, void *data) | |||
| 35 | static int dma_setup(struct scsi_cmnd *cmd, int dir_in) | 40 | static int dma_setup(struct scsi_cmnd *cmd, int dir_in) |
| 36 | { | 41 | { |
| 37 | struct Scsi_Host *instance = cmd->device->host; | 42 | struct Scsi_Host *instance = cmd->device->host; |
| 38 | struct WD33C93_hostdata *hdata = shost_priv(instance); | 43 | struct a2091_hostdata *hdata = shost_priv(instance); |
| 39 | struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); | 44 | struct WD33C93_hostdata *wh = &hdata->wh; |
| 45 | struct a2091_scsiregs *regs = hdata->regs; | ||
| 40 | unsigned short cntr = CNTR_PDMD | CNTR_INTEN; | 46 | unsigned short cntr = CNTR_PDMD | CNTR_INTEN; |
| 41 | unsigned long addr = virt_to_bus(cmd->SCp.ptr); | 47 | unsigned long addr = virt_to_bus(cmd->SCp.ptr); |
| 42 | 48 | ||
| 43 | /* don't allow DMA if the physical address is bad */ | 49 | /* don't allow DMA if the physical address is bad */ |
| 44 | if (addr & A2091_XFER_MASK) { | 50 | if (addr & A2091_XFER_MASK) { |
| 45 | hdata->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; | 51 | wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; |
| 46 | hdata->dma_bounce_buffer = kmalloc(hdata->dma_bounce_len, | 52 | wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len, |
| 47 | GFP_KERNEL); | 53 | GFP_KERNEL); |
| 48 | 54 | ||
| 49 | /* can't allocate memory; use PIO */ | 55 | /* can't allocate memory; use PIO */ |
| 50 | if (!hdata->dma_bounce_buffer) { | 56 | if (!wh->dma_bounce_buffer) { |
| 51 | hdata->dma_bounce_len = 0; | 57 | wh->dma_bounce_len = 0; |
| 52 | return 1; | 58 | return 1; |
| 53 | } | 59 | } |
| 54 | 60 | ||
| 55 | /* get the physical address of the bounce buffer */ | 61 | /* get the physical address of the bounce buffer */ |
| 56 | addr = virt_to_bus(hdata->dma_bounce_buffer); | 62 | addr = virt_to_bus(wh->dma_bounce_buffer); |
| 57 | 63 | ||
| 58 | /* the bounce buffer may not be in the first 16M of physmem */ | 64 | /* the bounce buffer may not be in the first 16M of physmem */ |
| 59 | if (addr & A2091_XFER_MASK) { | 65 | if (addr & A2091_XFER_MASK) { |
| 60 | /* we could use chipmem... maybe later */ | 66 | /* we could use chipmem... maybe later */ |
| 61 | kfree(hdata->dma_bounce_buffer); | 67 | kfree(wh->dma_bounce_buffer); |
| 62 | hdata->dma_bounce_buffer = NULL; | 68 | wh->dma_bounce_buffer = NULL; |
| 63 | hdata->dma_bounce_len = 0; | 69 | wh->dma_bounce_len = 0; |
| 64 | return 1; | 70 | return 1; |
| 65 | } | 71 | } |
| 66 | 72 | ||
| 67 | if (!dir_in) { | 73 | if (!dir_in) { |
| 68 | /* copy to bounce buffer for a write */ | 74 | /* copy to bounce buffer for a write */ |
| 69 | memcpy(hdata->dma_bounce_buffer, cmd->SCp.ptr, | 75 | memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr, |
| 70 | cmd->SCp.this_residual); | 76 | cmd->SCp.this_residual); |
| 71 | } | 77 | } |
| 72 | } | 78 | } |
| @@ -76,7 +82,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) | |||
| 76 | cntr |= CNTR_DDIR; | 82 | cntr |= CNTR_DDIR; |
| 77 | 83 | ||
| 78 | /* remember direction */ | 84 | /* remember direction */ |
| 79 | hdata->dma_dir = dir_in; | 85 | wh->dma_dir = dir_in; |
| 80 | 86 | ||
| 81 | regs->CNTR = cntr; | 87 | regs->CNTR = cntr; |
| 82 | 88 | ||
| @@ -100,20 +106,21 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) | |||
| 100 | static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, | 106 | static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, |
| 101 | int status) | 107 | int status) |
| 102 | { | 108 | { |
| 103 | struct WD33C93_hostdata *hdata = shost_priv(instance); | 109 | struct a2091_hostdata *hdata = shost_priv(instance); |
| 104 | struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); | 110 | struct WD33C93_hostdata *wh = &hdata->wh; |
| 111 | struct a2091_scsiregs *regs = hdata->regs; | ||
| 105 | 112 | ||
| 106 | /* disable SCSI interrupts */ | 113 | /* disable SCSI interrupts */ |
| 107 | unsigned short cntr = CNTR_PDMD; | 114 | unsigned short cntr = CNTR_PDMD; |
| 108 | 115 | ||
| 109 | if (!hdata->dma_dir) | 116 | if (!wh->dma_dir) |
| 110 | cntr |= CNTR_DDIR; | 117 | cntr |= CNTR_DDIR; |
| 111 | 118 | ||
| 112 | /* disable SCSI interrupts */ | 119 | /* disable SCSI interrupts */ |
| 113 | regs->CNTR = cntr; | 120 | regs->CNTR = cntr; |
| 114 | 121 | ||
| 115 | /* flush if we were reading */ | 122 | /* flush if we were reading */ |
| 116 | if (hdata->dma_dir) { | 123 | if (wh->dma_dir) { |
| 117 | regs->FLUSH = 1; | 124 | regs->FLUSH = 1; |
| 118 | while (!(regs->ISTR & ISTR_FE_FLG)) | 125 | while (!(regs->ISTR & ISTR_FE_FLG)) |
| 119 | ; | 126 | ; |
| @@ -129,13 +136,13 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, | |||
| 129 | regs->CNTR = CNTR_PDMD | CNTR_INTEN; | 136 | regs->CNTR = CNTR_PDMD | CNTR_INTEN; |
| 130 | 137 | ||
| 131 | /* copy from a bounce buffer, if necessary */ | 138 | /* copy from a bounce buffer, if necessary */ |
| 132 | if (status && hdata->dma_bounce_buffer) { | 139 | if (status && wh->dma_bounce_buffer) { |
| 133 | if (hdata->dma_dir) | 140 | if (wh->dma_dir) |
| 134 | memcpy(SCpnt->SCp.ptr, hdata->dma_bounce_buffer, | 141 | memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer, |
| 135 | SCpnt->SCp.this_residual); | 142 | SCpnt->SCp.this_residual); |
| 136 | kfree(hdata->dma_bounce_buffer); | 143 | kfree(wh->dma_bounce_buffer); |
| 137 | hdata->dma_bounce_buffer = NULL; | 144 | wh->dma_bounce_buffer = NULL; |
| 138 | hdata->dma_bounce_len = 0; | 145 | wh->dma_bounce_len = 0; |
| 139 | } | 146 | } |
| 140 | } | 147 | } |
| 141 | 148 | ||
| @@ -178,32 +185,32 @@ static int __devinit a2091_probe(struct zorro_dev *z, | |||
| 178 | int error; | 185 | int error; |
| 179 | struct a2091_scsiregs *regs; | 186 | struct a2091_scsiregs *regs; |
| 180 | wd33c93_regs wdregs; | 187 | wd33c93_regs wdregs; |
| 181 | struct WD33C93_hostdata *hdata; | 188 | struct a2091_hostdata *hdata; |
| 182 | 189 | ||
| 183 | if (!request_mem_region(z->resource.start, 256, "wd33c93")) | 190 | if (!request_mem_region(z->resource.start, 256, "wd33c93")) |
| 184 | return -EBUSY; | 191 | return -EBUSY; |
| 185 | 192 | ||
| 186 | instance = scsi_host_alloc(&a2091_scsi_template, | 193 | instance = scsi_host_alloc(&a2091_scsi_template, |
| 187 | sizeof(struct WD33C93_hostdata)); | 194 | sizeof(struct a2091_hostdata)); |
| 188 | if (!instance) { | 195 | if (!instance) { |
| 189 | error = -ENOMEM; | 196 | error = -ENOMEM; |
| 190 | goto fail_alloc; | 197 | goto fail_alloc; |
| 191 | } | 198 | } |
| 192 | 199 | ||
| 193 | instance->base = ZTWO_VADDR(z->resource.start); | ||
| 194 | instance->irq = IRQ_AMIGA_PORTS; | 200 | instance->irq = IRQ_AMIGA_PORTS; |
| 195 | instance->unique_id = z->slotaddr; | 201 | instance->unique_id = z->slotaddr; |
| 196 | 202 | ||
| 197 | regs = (struct a2091_scsiregs *)(instance->base); | 203 | regs = (struct a2091_scsiregs *)ZTWO_VADDR(z->resource.start); |
| 198 | regs->DAWR = DAWR_A2091; | 204 | regs->DAWR = DAWR_A2091; |
| 199 | 205 | ||
| 200 | wdregs.SASR = ®s->SASR; | 206 | wdregs.SASR = ®s->SASR; |
| 201 | wdregs.SCMD = ®s->SCMD; | 207 | wdregs.SCMD = ®s->SCMD; |
| 202 | 208 | ||
| 203 | hdata = shost_priv(instance); | 209 | hdata = shost_priv(instance); |
| 204 | hdata->no_sync = 0xff; | 210 | hdata->wh.no_sync = 0xff; |
| 205 | hdata->fast = 0; | 211 | hdata->wh.fast = 0; |
| 206 | hdata->dma_mode = CTRL_DMA; | 212 | hdata->wh.dma_mode = CTRL_DMA; |
| 213 | hdata->regs = regs; | ||
| 207 | 214 | ||
| 208 | wd33c93_init(instance, wdregs, dma_setup, dma_stop, WD33C93_FS_8_10); | 215 | wd33c93_init(instance, wdregs, dma_setup, dma_stop, WD33C93_FS_8_10); |
| 209 | error = request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, | 216 | error = request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, |
| @@ -234,9 +241,9 @@ fail_alloc: | |||
| 234 | static void __devexit a2091_remove(struct zorro_dev *z) | 241 | static void __devexit a2091_remove(struct zorro_dev *z) |
| 235 | { | 242 | { |
| 236 | struct Scsi_Host *instance = zorro_get_drvdata(z); | 243 | struct Scsi_Host *instance = zorro_get_drvdata(z); |
| 237 | struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); | 244 | struct a2091_hostdata *hdata = shost_priv(instance); |
| 238 | 245 | ||
| 239 | regs->CNTR = 0; | 246 | hdata->regs->CNTR = 0; |
| 240 | scsi_remove_host(instance); | 247 | scsi_remove_host(instance); |
| 241 | free_irq(IRQ_AMIGA_PORTS, instance); | 248 | free_irq(IRQ_AMIGA_PORTS, instance); |
| 242 | scsi_host_put(instance); | 249 | scsi_host_put(instance); |
