From c95e62ce8905aab62fed224eaaa9b8558a0ef652 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 23 Jun 2008 09:14:31 -0600 Subject: [SCSI] ses: Fix timeout Timeouts are measured in jiffies, not in seconds. Signed-off-by: Matthew Wilcox Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/scsi/ses.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 45df83b9d84..0fe031f003e 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -61,7 +61,7 @@ static int ses_probe(struct device *dev) return err; } -#define SES_TIMEOUT 30 +#define SES_TIMEOUT (30 * HZ) #define SES_RETRIES 3 static int ses_recv_diag(struct scsi_device *sdev, int page_code, -- cgit v1.2.3 From eadc49b1a8d09480f14caea292142f103a89c77a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 17 Jun 2008 23:53:22 -0700 Subject: [SCSI] esp: Fix OOPS in esp_reset_cleanup(). OOPS reported by Friedrich Oslage The problem here is that tp->starget is set every time a lun is allocated for a particular target so we can catch the sdev_target parent value. The reset handler uses the NULL'ness of this value to determine which targets are active. But esp_slave_destroy() does not NULL out this value when appropriate. So for every target that doesn't respond, the SCSI bus scan causes a stale pointer to be left here, with ensuing crashes like you're seeing. Signed-off-by: David S. Miller Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/scsi/esp_scsi.c | 8 ++++++++ drivers/scsi/esp_scsi.h | 1 + 2 files changed, 9 insertions(+) (limited to 'drivers/scsi') diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index a0b6d414953..305eddef5ca 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -2371,6 +2371,7 @@ static int esp_slave_alloc(struct scsi_device *dev) dev->hostdata = lp; tp->starget = dev->sdev_target; + tp->starget_ref++; spi_min_period(tp->starget) = esp->min_period; spi_max_offset(tp->starget) = 15; @@ -2425,10 +2426,17 @@ static int esp_slave_configure(struct scsi_device *dev) static void esp_slave_destroy(struct scsi_device *dev) { + struct esp *esp = shost_priv(dev->host); + struct esp_target_data *tp = &esp->target[dev->id]; struct esp_lun_data *lp = dev->hostdata; kfree(lp); dev->hostdata = NULL; + + BUG_ON(tp->starget_ref <= 0); + + if (!--tp->starget_ref) + tp->starget = NULL; } static int esp_eh_abort_handler(struct scsi_cmnd *cmd) diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index bb43a138818..655e0b2240b 100644 --- a/drivers/scsi/esp_scsi.h +++ b/drivers/scsi/esp_scsi.h @@ -322,6 +322,7 @@ struct esp_target_data { u8 nego_goal_tags; struct scsi_target *starget; + int starget_ref; }; struct esp_event_ent { -- cgit v1.2.3 From ec5e69f6d3f4350681d6f7eaae515cf014be9276 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 23 Jun 2008 14:52:09 -0500 Subject: [SCSI] esp: tidy up target reference counting The esp driver currently does hand rolled reference counting of its target. It's much easier to do what it needs to do if it's plugged into the mid-layer callbacks (target_alloc and target_destroy) which were designed for this case, so do it this way and get rid of the internal target reference count. Acked-by: David S. Miller Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/scsi/esp_scsi.c | 30 ++++++++++++++++++++---------- drivers/scsi/esp_scsi.h | 1 - 2 files changed, 20 insertions(+), 11 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 305eddef5ca..59fbef08d69 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -2359,6 +2359,24 @@ void scsi_esp_unregister(struct esp *esp) } EXPORT_SYMBOL(scsi_esp_unregister); +static int esp_target_alloc(struct scsi_target *starget) +{ + struct esp *esp = shost_priv(dev_to_shost(&starget->dev)); + struct esp_target_data *tp = &esp->target[starget->id]; + + tp->starget = starget; + + return 0; +} + +static void esp_target_destroy(struct scsi_target *starget) +{ + struct esp *esp = shost_priv(dev_to_shost(&starget->dev)); + struct esp_target_data *tp = &esp->target[starget->id]; + + tp->starget = NULL; +} + static int esp_slave_alloc(struct scsi_device *dev) { struct esp *esp = shost_priv(dev->host); @@ -2370,9 +2388,6 @@ static int esp_slave_alloc(struct scsi_device *dev) return -ENOMEM; dev->hostdata = lp; - tp->starget = dev->sdev_target; - tp->starget_ref++; - spi_min_period(tp->starget) = esp->min_period; spi_max_offset(tp->starget) = 15; @@ -2426,17 +2441,10 @@ static int esp_slave_configure(struct scsi_device *dev) static void esp_slave_destroy(struct scsi_device *dev) { - struct esp *esp = shost_priv(dev->host); - struct esp_target_data *tp = &esp->target[dev->id]; struct esp_lun_data *lp = dev->hostdata; kfree(lp); dev->hostdata = NULL; - - BUG_ON(tp->starget_ref <= 0); - - if (!--tp->starget_ref) - tp->starget = NULL; } static int esp_eh_abort_handler(struct scsi_cmnd *cmd) @@ -2616,6 +2624,8 @@ struct scsi_host_template scsi_esp_template = { .name = "esp", .info = esp_info, .queuecommand = esp_queuecommand, + .target_alloc = esp_target_alloc, + .target_destroy = esp_target_destroy, .slave_alloc = esp_slave_alloc, .slave_configure = esp_slave_configure, .slave_destroy = esp_slave_destroy, diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index 655e0b2240b..bb43a138818 100644 --- a/drivers/scsi/esp_scsi.h +++ b/drivers/scsi/esp_scsi.h @@ -322,7 +322,6 @@ struct esp_target_data { u8 nego_goal_tags; struct scsi_target *starget; - int starget_ref; }; struct esp_event_ent { -- cgit v1.2.3 From d8f8eb43e9d6d5789f37c8a80db99af894944d41 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Apr 2008 15:20:23 +0100 Subject: [ARM] rpc: acornscsi: remove unused 'ADDR' macro Acked-by: James Bottomley Signed-off-by: Russell King --- drivers/scsi/arm/acornscsi-io.S | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/arm/acornscsi-io.S b/drivers/scsi/arm/acornscsi-io.S index 93467e6ac92..3c5d4f8485d 100644 --- a/drivers/scsi/arm/acornscsi-io.S +++ b/drivers/scsi/arm/acornscsi-io.S @@ -10,19 +10,6 @@ #include #include -#if (IO_BASE == (PCIO_BASE & 0xff000000)) -#define ADDR(off,reg) \ - tst off, $0x80000000 ;\ - mov reg, $IO_BASE ;\ - orreq reg, reg, $(PCIO_BASE & 0x00ff0000) -#else -#define ADDR(off,reg) \ - tst off, $0x80000000 ;\ - movne reg, $IO_BASE ;\ - moveq reg, $(PCIO_BASE & 0xff000000) ;\ - orreq reg, reg, $(PCIO_BASE & 0x00ff0000) -#endif - @ Purpose: transfer a block of data from the acorn scsi card to memory @ Proto : void acornscsi_in(unsigned int addr_start, char *buffer, int length) @ Returns: nothing -- cgit v1.2.3 From 324b9337f246e5f00aad10220d8d4bc13f1922ed Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Apr 2008 15:13:45 +0100 Subject: [ARM] rpc: acornscsi: fixup abort/reset methods, fix build errors Revive the AcornSCSI driver, update it for the replacement command abort and host reset methods, and fix the build errors in acornscsi-io.S. Acked-by: James Bottomley Signed-off-by: Russell King --- drivers/scsi/arm/Kconfig | 2 +- drivers/scsi/arm/acornscsi-io.S | 6 ++++++ drivers/scsi/arm/acornscsi.c | 38 +++++++++----------------------------- 3 files changed, 16 insertions(+), 30 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/arm/Kconfig b/drivers/scsi/arm/Kconfig index 7236143941f..a8587f1f5e7 100644 --- a/drivers/scsi/arm/Kconfig +++ b/drivers/scsi/arm/Kconfig @@ -3,7 +3,7 @@ # config SCSI_ACORNSCSI_3 tristate "Acorn SCSI card (aka30) support" - depends on ARCH_ACORN && SCSI && BROKEN + depends on ARCH_ACORN && SCSI select SCSI_SPI_ATTRS help This enables support for the Acorn SCSI card (aka30). If you have an diff --git a/drivers/scsi/arm/acornscsi-io.S b/drivers/scsi/arm/acornscsi-io.S index 3c5d4f8485d..5cebe310526 100644 --- a/drivers/scsi/arm/acornscsi-io.S +++ b/drivers/scsi/arm/acornscsi-io.S @@ -10,6 +10,12 @@ #include #include +#if defined(__APCS_32__) +#define LOADREGS(t,r,l...) ldm##t r, l +#elif defined(__APCS_26__) +#define LOADREGS(t,r,l...) ldm##t r, l##^ +#endif + @ Purpose: transfer a block of data from the acorn scsi card to memory @ Proto : void acornscsi_in(unsigned int addr_start, char *buffer, int length) @ Returns: nothing diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index 8e53f02cc31..fa58d02ad0b 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -2731,9 +2731,7 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt) //#if (DEBUG & DEBUG_ABORT) printk("success\n"); //#endif - SCpnt->result = DID_ABORT << 16; - SCpnt->scsi_done(SCpnt); - result = SCSI_ABORT_SUCCESS; + result = SUCCESS; break; /* @@ -2745,7 +2743,7 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt) //#if (DEBUG & DEBUG_ABORT) printk("snooze\n"); //#endif - result = SCSI_ABORT_SNOOZE; + result = FAILED; break; /* @@ -2755,11 +2753,7 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt) default: case res_not_running: acornscsi_dumplog(host, SCpnt->device->id); -#if (DEBUG & DEBUG_ABORT) - result = SCSI_ABORT_SNOOZE; -#else - result = SCSI_ABORT_NOT_RUNNING; -#endif + result = FAILED; //#if (DEBUG & DEBUG_ABORT) printk("not running\n"); //#endif @@ -2770,13 +2764,12 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt) } /* - * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags) + * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt) * Purpose : reset a command on this host/reset this host * Params : SCpnt - command causing reset - * result - what type of reset to perform * Returns : one of SCSI_RESET_ macros */ -int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags) +int acornscsi_bus_reset(struct scsi_cmnd *SCpnt) { AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata; struct scsi_cmnd *SCptr; @@ -2798,28 +2791,16 @@ int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags) acornscsi_dma_stop(host); - SCptr = host->SCpnt; - /* * do hard reset. This resets all devices on this host, and so we * must set the reset status on all commands. */ acornscsi_resetcard(host); - /* - * report reset on commands current connected/disconnected - */ - acornscsi_reportstatus(&host->SCpnt, &SCptr, DID_RESET); - while ((SCptr = queue_remove(&host->queues.disconnected)) != NULL) - acornscsi_reportstatus(&SCptr, &SCpnt, DID_RESET); - - if (SCpnt) { - SCpnt->result = DID_RESET << 16; - SCpnt->scsi_done(SCpnt); - } + ; - return SCSI_RESET_BUS_RESET | SCSI_RESET_HOST_RESET | SCSI_RESET_SUCCESS; + return SUCCESS; } /*============================================================================================== @@ -2976,9 +2957,8 @@ static struct scsi_host_template acornscsi_template = { .name = "AcornSCSI", .info = acornscsi_info, .queuecommand = acornscsi_queuecmd, -#warning fixme - .abort = acornscsi_abort, - .reset = acornscsi_reset, + .eh_abort_handler = acornscsi_abort, + .eh_bus_reset_handler = acornscsi_bus_reset, .can_queue = 16, .this_id = 7, .sg_tablesize = SG_ALL, -- cgit v1.2.3 From ffd7858dd8ebb93fad700b830b3b9f6d024c9eac Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Apr 2008 14:26:18 +0100 Subject: [ARM] rpc: acornscsi: convert hardware accessors to take 'AS_Host *' Acked-by: James Bottomley Signed-off-by: Russell King --- drivers/scsi/arm/acornscsi.c | 243 +++++++++++++++++++++---------------------- 1 file changed, 120 insertions(+), 123 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index fa58d02ad0b..157ac1bf16f 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -203,44 +203,41 @@ static void acornscsi_abortcmd(AS_Host *host, unsigned char tag); * Miscellaneous */ -static inline void -sbic_arm_write(unsigned int io_port, int reg, int value) +static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value) { - __raw_writeb(reg, io_port); - __raw_writeb(value, io_port + 4); + __raw_writeb(reg, host->scsi.io_port); + __raw_writeb(value, host->scsi.io_port + 4); } -#define sbic_arm_writenext(io,val) \ - __raw_writeb((val), (io) + 4) +#define sbic_arm_writenext(host,val) \ + __raw_writeb((val), (host)->scsi.io_port + 4) -static inline -int sbic_arm_read(unsigned int io_port, int reg) +static inline int sbic_arm_read(AS_Host *host, unsigned int reg) { if(reg == SBIC_ASR) - return __raw_readl(io_port) & 255; - __raw_writeb(reg, io_port); - return __raw_readl(io_port + 4) & 255; + return __raw_readl(host->scsi.io_port) & 255; + __raw_writeb(reg, host->scsi.io_port); + return __raw_readl(host->scsi.io_port + 4) & 255; } -#define sbic_arm_readnext(io) \ - __raw_readb((io) + 4) +#define sbic_arm_readnext(host) \ + __raw_readb((host)->scsi.io_port + 4) #ifdef USE_DMAC -#define dmac_read(io_port,reg) \ - inb((io_port) + (reg)) +#define dmac_read(host,reg) \ + inb((host)->dma.io_port + (reg)) -#define dmac_write(io_port,reg,value) \ - ({ outb((value), (io_port) + (reg)); }) +#define dmac_write(host,reg,value) \ + ({ outb((value), (host)->dma.io_port + (reg)); }) -#define dmac_clearintr(io_port) \ - ({ outb(0, (io_port)); }) +#define dmac_clearintr(host) \ + ({ outb(0, (host)->dma.io_intr_clear); }) -static inline -unsigned int dmac_address(unsigned int io_port) +static inline unsigned int dmac_address(AS_Host *host) { - return dmac_read(io_port, DMAC_TXADRHI) << 16 | - dmac_read(io_port, DMAC_TXADRMD) << 8 | - dmac_read(io_port, DMAC_TXADRLO); + return dmac_read(host, DMAC_TXADRHI) << 16 | + dmac_read(host, DMAC_TXADRMD) << 8 | + dmac_read(host, DMAC_TXADRLO); } static @@ -248,15 +245,15 @@ void acornscsi_dumpdma(AS_Host *host, char *where) { unsigned int mode, addr, len; - mode = dmac_read(host->dma.io_port, DMAC_MODECON); - addr = dmac_address(host->dma.io_port); - len = dmac_read(host->dma.io_port, DMAC_TXCNTHI) << 8 | - dmac_read(host->dma.io_port, DMAC_TXCNTLO); + mode = dmac_read(host, DMAC_MODECON); + addr = dmac_address(host); + len = dmac_read(host, DMAC_TXCNTHI) << 8 | + dmac_read(host, DMAC_TXCNTLO); printk("scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ", host->host->host_no, where, mode, addr, (len + 1) & 0xffff, - dmac_read(host->dma.io_port, DMAC_MASKREG)); + dmac_read(host, DMAC_MASKREG)); printk("DMA @%06x, ", host->dma.start_addr); printk("BH @%p +%04x, ", host->scsi.SCp.ptr, @@ -272,9 +269,9 @@ unsigned long acornscsi_sbic_xfcount(AS_Host *host) { unsigned long length; - length = sbic_arm_read(host->scsi.io_port, SBIC_TRANSCNTH) << 16; - length |= sbic_arm_readnext(host->scsi.io_port) << 8; - length |= sbic_arm_readnext(host->scsi.io_port); + length = sbic_arm_read(host, SBIC_TRANSCNTH) << 16; + length |= sbic_arm_readnext(host) << 8; + length |= sbic_arm_readnext(host); return length; } @@ -285,7 +282,7 @@ acornscsi_sbic_wait(AS_Host *host, int stat_mask, int stat, int timeout, char *m int asr; do { - asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR); + asr = sbic_arm_read(host, SBIC_ASR); if ((asr & stat_mask) == stat) return 0; @@ -304,7 +301,7 @@ int acornscsi_sbic_issuecmd(AS_Host *host, int command) if (acornscsi_sbic_wait(host, ASR_CIP, 0, 1000, "issuing command")) return -1; - sbic_arm_write(host->scsi.io_port, SBIC_CMND, command); + sbic_arm_write(host, SBIC_CMND, command); return 0; } @@ -353,12 +350,12 @@ void acornscsi_resetcard(AS_Host *host) printk("scsi%d: timeout while resetting card\n", host->host->host_no); - sbic_arm_read(host->scsi.io_port, SBIC_ASR); - sbic_arm_read(host->scsi.io_port, SBIC_SSR); + sbic_arm_read(host, SBIC_ASR); + sbic_arm_read(host, SBIC_SSR); /* setup sbic - WD33C93A */ - sbic_arm_write(host->scsi.io_port, SBIC_OWNID, OWNID_EAF | host->host->this_id); - sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_RESET); + sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id); + sbic_arm_write(host, SBIC_CMND, CMND_RESET); /* * Command should cause a reset interrupt @@ -374,26 +371,26 @@ void acornscsi_resetcard(AS_Host *host) printk("scsi%d: timeout while resetting card\n", host->host->host_no); - sbic_arm_read(host->scsi.io_port, SBIC_ASR); - if (sbic_arm_read(host->scsi.io_port, SBIC_SSR) != 0x01) + sbic_arm_read(host, SBIC_ASR); + if (sbic_arm_read(host, SBIC_SSR) != 0x01) printk(KERN_CRIT "scsi%d: WD33C93A didn't give enhanced reset interrupt\n", host->host->host_no); - sbic_arm_write(host->scsi.io_port, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI); - sbic_arm_write(host->scsi.io_port, SBIC_TIMEOUT, TIMEOUT_TIME); - sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA); - sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); + sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI); + sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME); + sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA); + sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); host->card.page_reg = 0x40; outb(host->card.page_reg, host->card.io_page); /* setup dmac - uPC71071 */ - dmac_write(host->dma.io_port, DMAC_INIT, 0); + dmac_write(host, DMAC_INIT, 0); #ifdef USE_DMAC - dmac_write(host->dma.io_port, DMAC_INIT, INIT_8BIT); - dmac_write(host->dma.io_port, DMAC_CHANNEL, CHANNEL_0); - dmac_write(host->dma.io_port, DMAC_DEVCON0, INIT_DEVCON0); - dmac_write(host->dma.io_port, DMAC_DEVCON1, INIT_DEVCON1); + dmac_write(host, DMAC_INIT, INIT_8BIT); + dmac_write(host, DMAC_CHANNEL, CHANNEL_0); + dmac_write(host, DMAC_DEVCON0, INIT_DEVCON0); + dmac_write(host, DMAC_DEVCON1, INIT_DEVCON1); #endif host->SCpnt = NULL; @@ -741,9 +738,9 @@ intr_ret_t acornscsi_kick(AS_Host *host) * If we have an interrupt pending, then we may have been reselected. * In this case, we don't want to write to the registers */ - if (!(sbic_arm_read(host->scsi.io_port, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) { - sbic_arm_write(host->scsi.io_port, SBIC_DESTID, SCpnt->device->id); - sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_SELWITHATN); + if (!(sbic_arm_read(host, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) { + sbic_arm_write(host, SBIC_DESTID, SCpnt->device->id); + sbic_arm_write(host, SBIC_CMND, CMND_SELWITHATN); } /* @@ -807,7 +804,7 @@ static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, struct scsi_cmnd *SCpnt = *SCpntp; /* clean up */ - sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); + sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); host->stats.fins += 1; @@ -1008,8 +1005,8 @@ void acornscsi_data_write(AS_Host *host, char *ptr, static inline void acornscsi_dma_stop(AS_Host *host) { - dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON); - dmac_clearintr(host->dma.io_intr_clear); + dmac_write(host, DMAC_MASKREG, MASK_ON); + dmac_clearintr(host); #if (DEBUG & DEBUG_DMA) DBG(host->SCpnt, acornscsi_dumpdma(host, "stop")); @@ -1031,7 +1028,7 @@ void acornscsi_dma_setup(AS_Host *host, dmadir_t direction) host->dma.direction = direction; - dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON); + dmac_write(host, DMAC_MASKREG, MASK_ON); if (direction == DMA_OUT) { #if (DEBUG & DEBUG_NO_WRITE) @@ -1062,13 +1059,13 @@ void acornscsi_dma_setup(AS_Host *host, dmadir_t direction) length); length -= 1; - dmac_write(host->dma.io_port, DMAC_TXCNTLO, length); - dmac_write(host->dma.io_port, DMAC_TXCNTHI, length >> 8); - dmac_write(host->dma.io_port, DMAC_TXADRLO, address); - dmac_write(host->dma.io_port, DMAC_TXADRMD, address >> 8); - dmac_write(host->dma.io_port, DMAC_TXADRHI, 0); - dmac_write(host->dma.io_port, DMAC_MODECON, mode); - dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF); + dmac_write(host, DMAC_TXCNTLO, length); + dmac_write(host, DMAC_TXCNTHI, length >> 8); + dmac_write(host, DMAC_TXADRLO, address); + dmac_write(host, DMAC_TXADRMD, address >> 8); + dmac_write(host, DMAC_TXADRHI, 0); + dmac_write(host, DMAC_MODECON, mode); + dmac_write(host, DMAC_MASKREG, MASK_OFF); #if (DEBUG & DEBUG_DMA) DBG(host->SCpnt, acornscsi_dumpdma(host, "strt")); @@ -1088,8 +1085,8 @@ void acornscsi_dma_setup(AS_Host *host, dmadir_t direction) static void acornscsi_dma_cleanup(AS_Host *host) { - dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON); - dmac_clearintr(host->dma.io_intr_clear); + dmac_write(host, DMAC_MASKREG, MASK_ON); + dmac_clearintr(host); /* * Check for a pending transfer @@ -1116,7 +1113,7 @@ void acornscsi_dma_cleanup(AS_Host *host) /* * Calculate number of bytes transferred from DMA. */ - transferred = dmac_address(host->dma.io_port) - host->dma.start_addr; + transferred = dmac_address(host) - host->dma.start_addr; host->dma.transferred += transferred; if (host->dma.direction == DMA_IN) @@ -1152,13 +1149,13 @@ void acornscsi_dma_intr(AS_Host *host) DBG(host->SCpnt, acornscsi_dumpdma(host, "inti")); #endif - dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON); - dmac_clearintr(host->dma.io_intr_clear); + dmac_write(host, DMAC_MASKREG, MASK_ON); + dmac_clearintr(host); /* * Calculate amount transferred via DMA */ - transferred = dmac_address(host->dma.io_port) - host->dma.start_addr; + transferred = dmac_address(host) - host->dma.start_addr; host->dma.transferred += transferred; /* @@ -1190,12 +1187,12 @@ void acornscsi_dma_intr(AS_Host *host) length); length -= 1; - dmac_write(host->dma.io_port, DMAC_TXCNTLO, length); - dmac_write(host->dma.io_port, DMAC_TXCNTHI, length >> 8); - dmac_write(host->dma.io_port, DMAC_TXADRLO, address); - dmac_write(host->dma.io_port, DMAC_TXADRMD, address >> 8); - dmac_write(host->dma.io_port, DMAC_TXADRHI, 0); - dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF); + dmac_write(host, DMAC_TXCNTLO, length); + dmac_write(host, DMAC_TXCNTHI, length >> 8); + dmac_write(host, DMAC_TXADRLO, address); + dmac_write(host, DMAC_TXADRMD, address >> 8); + dmac_write(host, DMAC_TXADRHI, 0); + dmac_write(host, DMAC_MASKREG, MASK_OFF); #if (DEBUG & DEBUG_DMA) DBG(host->SCpnt, acornscsi_dumpdma(host, "into")); @@ -1209,15 +1206,15 @@ void acornscsi_dma_intr(AS_Host *host) * attention condition. We continue giving one byte until * the device recognises the attention. */ - if (dmac_read(host->dma.io_port, DMAC_STATUS) & STATUS_RQ0) { + if (dmac_read(host, DMAC_STATUS) & STATUS_RQ0) { acornscsi_abortcmd(host, host->SCpnt->tag); - dmac_write(host->dma.io_port, DMAC_TXCNTLO, 0); - dmac_write(host->dma.io_port, DMAC_TXCNTHI, 0); - dmac_write(host->dma.io_port, DMAC_TXADRLO, 0); - dmac_write(host->dma.io_port, DMAC_TXADRMD, 0); - dmac_write(host->dma.io_port, DMAC_TXADRHI, 0); - dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF); + dmac_write(host, DMAC_TXCNTLO, 0); + dmac_write(host, DMAC_TXCNTHI, 0); + dmac_write(host, DMAC_TXADRLO, 0); + dmac_write(host, DMAC_TXADRMD, 0); + dmac_write(host, DMAC_TXADRHI, 0); + dmac_write(host, DMAC_MASKREG, MASK_OFF); } #endif } @@ -1271,9 +1268,9 @@ void acornscsi_dma_adjust(AS_Host *host) host->dma.xfer_setup = 0; else { transferred += host->dma.start_addr; - dmac_write(host->dma.io_port, DMAC_TXADRLO, transferred); - dmac_write(host->dma.io_port, DMAC_TXADRMD, transferred >> 8); - dmac_write(host->dma.io_port, DMAC_TXADRHI, transferred >> 16); + dmac_write(host, DMAC_TXADRLO, transferred); + dmac_write(host, DMAC_TXADRMD, transferred >> 8); + dmac_write(host, DMAC_TXADRHI, transferred >> 16); #if (DEBUG & (DEBUG_DMA|DEBUG_WRITE)) DBG(host->SCpnt, acornscsi_dumpdma(host, "adjo")); #endif @@ -1292,12 +1289,12 @@ acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int int my_ptr = *ptr; while (my_ptr < len) { - asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR); + asr = sbic_arm_read(host, SBIC_ASR); if (asr & ASR_DBR) { timeout = max_timeout; - sbic_arm_write(host->scsi.io_port, SBIC_DATA, bytes[my_ptr++]); + sbic_arm_write(host, SBIC_DATA, bytes[my_ptr++]); } else if (asr & ASR_INT) break; else if (--timeout == 0) @@ -1320,9 +1317,9 @@ acornscsi_sendcommand(AS_Host *host) { struct scsi_cmnd *SCpnt = host->SCpnt; - sbic_arm_write(host->scsi.io_port, SBIC_TRANSCNTH, 0); - sbic_arm_writenext(host->scsi.io_port, 0); - sbic_arm_writenext(host->scsi.io_port, SCpnt->cmd_len - host->scsi.SCp.sent_command); + sbic_arm_write(host, SBIC_TRANSCNTH, 0); + sbic_arm_writenext(host, 0); + sbic_arm_writenext(host, SCpnt->cmd_len - host->scsi.SCp.sent_command); acornscsi_sbic_issuecmd(host, CMND_XFERINFO); @@ -1351,7 +1348,7 @@ void acornscsi_sendmessage(AS_Host *host) acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 1"); - sbic_arm_write(host->scsi.io_port, SBIC_DATA, NOP); + sbic_arm_write(host, SBIC_DATA, NOP); host->scsi.last_message = NOP; #if (DEBUG & DEBUG_MESSAGES) @@ -1365,7 +1362,7 @@ void acornscsi_sendmessage(AS_Host *host) acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 2"); - sbic_arm_write(host->scsi.io_port, SBIC_DATA, msg->msg[0]); + sbic_arm_write(host, SBIC_DATA, msg->msg[0]); host->scsi.last_message = msg->msg[0]; #if (DEBUG & DEBUG_MESSAGES) @@ -1382,9 +1379,9 @@ void acornscsi_sendmessage(AS_Host *host) * initiator. This provides an interlock so that the * initiator can determine which message byte is rejected. */ - sbic_arm_write(host->scsi.io_port, SBIC_TRANSCNTH, 0); - sbic_arm_writenext(host->scsi.io_port, 0); - sbic_arm_writenext(host->scsi.io_port, message_length); + sbic_arm_write(host, SBIC_TRANSCNTH, 0); + sbic_arm_writenext(host, 0); + sbic_arm_writenext(host, message_length); acornscsi_sbic_issuecmd(host, CMND_XFERINFO); msgnr = 0; @@ -1421,7 +1418,7 @@ void acornscsi_readstatusbyte(AS_Host *host) { acornscsi_sbic_issuecmd(host, CMND_XFERINFO|CMND_SBT); acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "reading status byte"); - host->scsi.SCp.Status = sbic_arm_read(host->scsi.io_port, SBIC_DATA); + host->scsi.SCp.Status = sbic_arm_read(host, SBIC_DATA); } /* @@ -1438,12 +1435,12 @@ unsigned char acornscsi_readmessagebyte(AS_Host *host) acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "for message byte"); - message = sbic_arm_read(host->scsi.io_port, SBIC_DATA); + message = sbic_arm_read(host, SBIC_DATA); /* wait for MSGIN-XFER-PAUSED */ acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after message byte"); - sbic_arm_read(host->scsi.io_port, SBIC_SSR); + sbic_arm_read(host, SBIC_SSR); return message; } @@ -1480,7 +1477,7 @@ void acornscsi_message(AS_Host *host) /* wait for next msg-in */ acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after negate ack"); - sbic_arm_read(host->scsi.io_port, SBIC_SSR); + sbic_arm_read(host, SBIC_SSR); } } while (msgidx < msglen); @@ -1602,7 +1599,7 @@ void acornscsi_message(AS_Host *host) host->host->host_no, acornscsi_target(host)); host->device[host->SCpnt->device->id].sync_xfer = SYNCHTRANSFER_2DBA; host->device[host->SCpnt->device->id].sync_state = SYNC_ASYNCHRONOUS; - sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); + sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); break; default: @@ -1652,7 +1649,7 @@ void acornscsi_message(AS_Host *host) host->device[host->SCpnt->device->id].sync_xfer = calc_sync_xfer(period * 4, length); } - sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); + sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); break; #else /* We do not accept synchronous transfers. Respond with a @@ -1792,10 +1789,10 @@ int acornscsi_starttransfer(AS_Host *host) residual = scsi_bufflen(host->SCpnt) - host->scsi.SCp.scsi_xferred; - sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); - sbic_arm_writenext(host->scsi.io_port, residual >> 16); - sbic_arm_writenext(host->scsi.io_port, residual >> 8); - sbic_arm_writenext(host->scsi.io_port, residual); + sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); + sbic_arm_writenext(host, residual >> 16); + sbic_arm_writenext(host, residual >> 8); + sbic_arm_writenext(host, residual); acornscsi_sbic_issuecmd(host, CMND_XFERINFO); return 1; } @@ -1816,7 +1813,7 @@ int acornscsi_reconnect(AS_Host *host) { unsigned int target, lun, ok = 0; - target = sbic_arm_read(host->scsi.io_port, SBIC_SOURCEID); + target = sbic_arm_read(host, SBIC_SOURCEID); if (!(target & 8)) printk(KERN_ERR "scsi%d: invalid source id after reselection " @@ -1832,7 +1829,7 @@ int acornscsi_reconnect(AS_Host *host) host->SCpnt = NULL; } - lun = sbic_arm_read(host->scsi.io_port, SBIC_DATA) & 7; + lun = sbic_arm_read(host, SBIC_DATA) & 7; host->scsi.reconnected.target = target; host->scsi.reconnected.lun = lun; @@ -1952,7 +1949,7 @@ static void acornscsi_abortcmd(AS_Host *host, unsigned char tag) { host->scsi.phase = PHASE_ABORTED; - sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_ASSERTATN); + sbic_arm_write(host, SBIC_CMND, CMND_ASSERTATN); msgqueue_flush(&host->scsi.msgs); #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE @@ -1979,11 +1976,11 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) { unsigned int asr, ssr; - asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR); + asr = sbic_arm_read(host, SBIC_ASR); if (!(asr & ASR_INT)) return INTR_IDLE; - ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR); + ssr = sbic_arm_read(host, SBIC_SSR); #if (DEBUG & DEBUG_PHASES) print_sbic_status(asr, ssr, host->scsi.phase); @@ -1999,15 +1996,15 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) printk(KERN_ERR "scsi%d: reset in standard mode but wanted advanced mode.\n", host->host->host_no); /* setup sbic - WD33C93A */ - sbic_arm_write(host->scsi.io_port, SBIC_OWNID, OWNID_EAF | host->host->this_id); - sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_RESET); + sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id); + sbic_arm_write(host, SBIC_CMND, CMND_RESET); return INTR_IDLE; case 0x01: /* reset state - advanced */ - sbic_arm_write(host->scsi.io_port, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI); - sbic_arm_write(host->scsi.io_port, SBIC_TIMEOUT, TIMEOUT_TIME); - sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA); - sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); + sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI); + sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME); + sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA); + sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); msgqueue_flush(&host->scsi.msgs); return INTR_IDLE; @@ -2025,10 +2022,10 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) msgqueue_flush(&host->scsi.msgs); host->dma.transferred = host->scsi.SCp.scsi_xferred; /* 33C93 gives next interrupt indicating bus phase */ - asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR); + asr = sbic_arm_read(host, SBIC_ASR); if (!(asr & ASR_INT)) break; - ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR); + ssr = sbic_arm_read(host, SBIC_SSR); ADD_STATUS(8, ssr, host->scsi.phase, 1); ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, 1); goto connected; @@ -2655,7 +2652,7 @@ static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt) * busylun bit. */ case PHASE_CONNECTED: - sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_DISCONNECT); + sbic_arm_write(host, SBIC_CMND, CMND_DISCONNECT); host->SCpnt = NULL; res = res_success_clear; break; @@ -2699,8 +2696,8 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt) #if (DEBUG & DEBUG_ABORT) { int asr, ssr; - asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR); - ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR); + asr = sbic_arm_read(host, SBIC_ASR); + ssr = sbic_arm_read(host, SBIC_SSR); printk(KERN_WARNING "acornscsi_abort: "); print_sbic_status(asr, ssr, host->scsi.phase); @@ -2780,8 +2777,8 @@ int acornscsi_bus_reset(struct scsi_cmnd *SCpnt) { int asr, ssr; - asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR); - ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR); + asr = sbic_arm_read(host, SBIC_ASR); + ssr = sbic_arm_read(host, SBIC_SSR); printk(KERN_WARNING "acornscsi_reset: "); print_sbic_status(asr, ssr, host->scsi.phase); -- cgit v1.2.3 From a796ef7035c6c5cc5726c3e4e8d71175c13828df Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Apr 2008 15:37:44 +0100 Subject: [ARM] rpc: acornscsi: stop using private __stringify() The kernel has its own, so let's use that instead. Acked-by: James Bottomley Signed-off-by: Russell King --- drivers/scsi/arm/acornscsi.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index 157ac1bf16f..a2f8113c3b0 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -123,12 +123,6 @@ #define DBG(cmd,xxx...) xxx #endif -#ifndef STRINGIFY -#define STRINGIFY(x) #x -#endif -#define STRx(x) STRINGIFY(x) -#define NO_WRITE_STR STRx(NO_WRITE) - #include #include #include @@ -141,6 +135,7 @@ #include #include #include +#include #include #include @@ -2828,7 +2823,7 @@ char *acornscsi_info(struct Scsi_Host *host) " LINK" #endif #if (DEBUG & DEBUG_NO_WRITE) - " NOWRITE ("NO_WRITE_STR")" + " NOWRITE (" __stringify(NO_WRITE) ")" #endif , host->hostt->name, host->io_port, host->irq, VER_MAJOR, VER_MINOR, VER_PATCH); @@ -2859,7 +2854,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, " LINK" #endif #if (DEBUG & DEBUG_NO_WRITE) - " NOWRITE ("NO_WRITE_STR")" + " NOWRITE (" __stringify(NO_WRITE) ")" #endif "\n\n", VER_MAJOR, VER_MINOR, VER_PATCH); -- cgit v1.2.3 From e95a1b656a9809acd8ba8eb867ac6a7759d6180e Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Apr 2008 15:42:57 +0100 Subject: [ARM] rpc: acornscsi: update to new style ecard driver Update acornscsi as per all the other ecard drivers to use MMIO accessors rather than the obsolete 'pc io' style inb/outb accessors. Use ecard_request_resources()/ecard_release_resources() for easier resource handling, rather than requesting 5 separate regions individually. Acked-by: James Bottomley Signed-off-by: Russell King --- drivers/scsi/arm/acornscsi.c | 160 ++++++++++++++++++++----------------------- drivers/scsi/arm/acornscsi.h | 9 +-- 2 files changed, 75 insertions(+), 94 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index a2f8113c3b0..918ccf81875 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -136,9 +136,9 @@ #include #include #include +#include #include -#include #include #include "../scsi.h" @@ -198,35 +198,40 @@ static void acornscsi_abortcmd(AS_Host *host, unsigned char tag); * Miscellaneous */ +/* Offsets from MEMC base */ +#define SBIC_REGIDX 0x2000 +#define SBIC_REGVAL 0x2004 +#define DMAC_OFFSET 0x3000 + +/* Offsets from FAST IOC base */ +#define INT_REG 0x2000 +#define PAGE_REG 0x3000 + static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value) { - __raw_writeb(reg, host->scsi.io_port); - __raw_writeb(value, host->scsi.io_port + 4); + writeb(reg, host->base + SBIC_REGIDX); + writeb(value, host->base + SBIC_REGVAL); } -#define sbic_arm_writenext(host,val) \ - __raw_writeb((val), (host)->scsi.io_port + 4) - static inline int sbic_arm_read(AS_Host *host, unsigned int reg) { if(reg == SBIC_ASR) - return __raw_readl(host->scsi.io_port) & 255; - __raw_writeb(reg, host->scsi.io_port); - return __raw_readl(host->scsi.io_port + 4) & 255; + return readl(host->base + SBIC_REGIDX) & 255; + writeb(reg, host->base + SBIC_REGIDX); + return readl(host->base + SBIC_REGVAL) & 255; } -#define sbic_arm_readnext(host) \ - __raw_readb((host)->scsi.io_port + 4) +#define sbic_arm_writenext(host, val) writeb((val), (host)->base + SBIC_REGVAL) +#define sbic_arm_readnext(host) readb((host)->base + SBIC_REGVAL) #ifdef USE_DMAC #define dmac_read(host,reg) \ - inb((host)->dma.io_port + (reg)) + readb((host)->base + DMAC_OFFSET + ((reg) << 2)) #define dmac_write(host,reg,value) \ - ({ outb((value), (host)->dma.io_port + (reg)); }) + ({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); }) -#define dmac_clearintr(host) \ - ({ outb(0, (host)->dma.io_intr_clear); }) +#define dmac_clearintr(host) writeb(0, (host)->fast + INT_REG) static inline unsigned int dmac_address(AS_Host *host) { @@ -323,20 +328,20 @@ void acornscsi_resetcard(AS_Host *host) /* assert reset line */ host->card.page_reg = 0x80; - outb(host->card.page_reg, host->card.io_page); + writeb(host->card.page_reg, host->fast + PAGE_REG); /* wait 3 cs. SCSI standard says 25ms. */ acornscsi_csdelay(3); host->card.page_reg = 0; - outb(host->card.page_reg, host->card.io_page); + writeb(host->card.page_reg, host->fast + PAGE_REG); /* * Should get a reset from the card */ timeout = 1000; do { - if (inb(host->card.io_intr) & 8) + if (readb(host->fast + INT_REG) & 8) break; udelay(1); } while (--timeout); @@ -357,7 +362,7 @@ void acornscsi_resetcard(AS_Host *host) */ timeout = 1000; do { - if (inb(host->card.io_intr) & 8) + if (readb(host->fast + INT_REG) & 8) break; udelay(1); } while (--timeout); @@ -377,7 +382,7 @@ void acornscsi_resetcard(AS_Host *host) sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); host->card.page_reg = 0x40; - outb(host->card.page_reg, host->card.io_page); + writeb(host->card.page_reg, host->fast + PAGE_REG); /* setup dmac - uPC71071 */ dmac_write(host, DMAC_INIT, 0); @@ -910,13 +915,13 @@ static void acornscsi_data_read(AS_Host *host, char *ptr, unsigned int start_addr, unsigned int length) { - extern void __acornscsi_in(int port, char *buf, int len); + extern void __acornscsi_in(void __iomem *, char *buf, int len); unsigned int page, offset, len = length; page = (start_addr >> 12); offset = start_addr & ((1 << 12) - 1); - outb((page & 0x3f) | host->card.page_reg, host->card.io_page); + writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); while (len > 0) { unsigned int this_len; @@ -926,7 +931,7 @@ void acornscsi_data_read(AS_Host *host, char *ptr, else this_len = len; - __acornscsi_in(host->card.io_ram + (offset << 1), ptr, this_len); + __acornscsi_in(host->base + (offset << 1), ptr, this_len); offset += this_len; ptr += this_len; @@ -935,10 +940,10 @@ void acornscsi_data_read(AS_Host *host, char *ptr, if (offset == (1 << 12)) { offset = 0; page ++; - outb((page & 0x3f) | host->card.page_reg, host->card.io_page); + writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); } } - outb(host->card.page_reg, host->card.io_page); + writeb(host->card.page_reg, host->fast + PAGE_REG); } /* @@ -955,13 +960,13 @@ static void acornscsi_data_write(AS_Host *host, char *ptr, unsigned int start_addr, unsigned int length) { - extern void __acornscsi_out(int port, char *buf, int len); + extern void __acornscsi_out(void __iomem *, char *buf, int len); unsigned int page, offset, len = length; page = (start_addr >> 12); offset = start_addr & ((1 << 12) - 1); - outb((page & 0x3f) | host->card.page_reg, host->card.io_page); + writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); while (len > 0) { unsigned int this_len; @@ -971,7 +976,7 @@ void acornscsi_data_write(AS_Host *host, char *ptr, else this_len = len; - __acornscsi_out(host->card.io_ram + (offset << 1), ptr, this_len); + __acornscsi_out(host->base + (offset << 1), ptr, this_len); offset += this_len; ptr += this_len; @@ -980,10 +985,10 @@ void acornscsi_data_write(AS_Host *host, char *ptr, if (offset == (1 << 12)) { offset = 0; page ++; - outb((page & 0x3f) | host->card.page_reg, host->card.io_page); + writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); } } - outb(host->card.page_reg, host->card.io_page); + writeb(host->card.page_reg, host->fast + PAGE_REG); } /* ========================================================================================= @@ -2468,11 +2473,11 @@ acornscsi_intr(int irq, void *dev_id) do { ret = INTR_IDLE; - iostatus = inb(host->card.io_intr); + iostatus = readb(host->fast + INT_REG); if (iostatus & 2) { acornscsi_dma_intr(host); - iostatus = inb(host->card.io_intr); + iostatus = readb(host->fast + INT_REG); } if (iostatus & 8) @@ -2858,11 +2863,11 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, #endif "\n\n", VER_MAJOR, VER_MINOR, VER_PATCH); - p += sprintf(p, "SBIC: WD33C93A Address: %08X IRQ : %d\n", - host->scsi.io_port, host->scsi.irq); + p += sprintf(p, "SBIC: WD33C93A Address: %p IRQ : %d\n", + host->base + SBIC_REGIDX, host->scsi.irq); #ifdef USE_DMAC - p += sprintf(p, "DMAC: uPC71071 Address: %08X IRQ : %d\n\n", - host->dma.io_port, host->scsi.irq); + p += sprintf(p, "DMAC: uPC71071 Address: %p IRQ : %d\n\n", + host->base + DMAC_OFFSET, host->scsi.irq); #endif p += sprintf(p, "Statistics:\n" @@ -2964,48 +2969,37 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; AS_Host *ashost; - int ret = -ENOMEM; + int ret; - host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host)); - if (!host) + ret = ecard_request_resources(ec); + if (ret) goto out; + host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host)); + if (!host) { + ret = -ENOMEM; + goto out_release; + } + ashost = (AS_Host *)host->hostdata; - host->io_port = ecard_address(ec, ECARD_MEMC, 0); - host->irq = ec->irq; + ashost->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); + ashost->fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); + if (!ashost->base || !ashost->fast) + goto out_put; - ashost->host = host; - ashost->scsi.io_port = ioaddr(host->io_port + 0x800); - ashost->scsi.irq = host->irq; - ashost->card.io_intr = POD_SPACE(host->io_port) + 0x800; - ashost->card.io_page = POD_SPACE(host->io_port) + 0xc00; - ashost->card.io_ram = ioaddr(host->io_port); - ashost->dma.io_port = host->io_port + 0xc00; - ashost->dma.io_intr_clear = POD_SPACE(host->io_port) + 0x800; + host->irq = ec->irq; + ashost->host = host; + ashost->scsi.irq = host->irq; - ec->irqaddr = (char *)ioaddr(ashost->card.io_intr); + ec->irqaddr = ashost->fast + INT_REG; ec->irqmask = 0x0a; - ret = -EBUSY; - if (!request_region(host->io_port + 0x800, 2, "acornscsi(sbic)")) - goto err_1; - if (!request_region(ashost->card.io_intr, 1, "acornscsi(intr)")) - goto err_2; - if (!request_region(ashost->card.io_page, 1, "acornscsi(page)")) - goto err_3; -#ifdef USE_DMAC - if (!request_region(ashost->dma.io_port, 256, "acornscsi(dmac)")) - goto err_4; -#endif - if (!request_region(host->io_port, 2048, "acornscsi(ram)")) - goto err_5; - ret = request_irq(host->irq, acornscsi_intr, IRQF_DISABLED, "acornscsi", ashost); if (ret) { printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n", host->host_no, ashost->scsi.irq, ret); - goto err_6; + goto out_put; } memset(&ashost->stats, 0, sizeof (ashost->stats)); @@ -3017,27 +3011,22 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id) ret = scsi_add_host(host, &ec->dev); if (ret) - goto err_7; + goto out_irq; scsi_scan_host(host); goto out; - err_7: + out_irq: free_irq(host->irq, ashost); - err_6: - release_region(host->io_port, 2048); - err_5: -#ifdef USE_DMAC - release_region(ashost->dma.io_port, 256); -#endif - err_4: - release_region(ashost->card.io_page, 1); - err_3: - release_region(ashost->card.io_intr, 1); - err_2: - release_region(host->io_port + 0x800, 2); - err_1: + msgqueue_free(&ashost->scsi.msgs); + queue_free(&ashost->queues.disconnected); + queue_free(&ashost->queues.issue); + out_put: + ecardm_iounmap(ec, ashost->fast); + ecardm_iounmap(ec, ashost->base); scsi_host_put(host); + out_release: + ecard_release_resources(ec); out: return ret; } @@ -3053,20 +3042,17 @@ static void __devexit acornscsi_remove(struct expansion_card *ec) /* * Put card into RESET state */ - outb(0x80, ashost->card.io_page); + writeb(0x80, ashost->fast + PAGE_REG); free_irq(host->irq, ashost); - release_region(host->io_port + 0x800, 2); - release_region(ashost->card.io_intr, 1); - release_region(ashost->card.io_page, 1); - release_region(ashost->dma.io_port, 256); - release_region(host->io_port, 2048); - msgqueue_free(&ashost->scsi.msgs); queue_free(&ashost->queues.disconnected); queue_free(&ashost->queues.issue); + ecardm_iounmap(ec, ashost->fast); + ecardm_iounmap(ec, ashost->base); scsi_host_put(host); + ecard_release_resources(ec); } static const struct ecard_id acornscsi_cids[] = { diff --git a/drivers/scsi/arm/acornscsi.h b/drivers/scsi/arm/acornscsi.h index d11424b89f4..8d2172a0b35 100644 --- a/drivers/scsi/arm/acornscsi.h +++ b/drivers/scsi/arm/acornscsi.h @@ -179,7 +179,6 @@ /* miscellaneous internal variables */ -#define POD_SPACE(x) ((x) + 0xd0000) #define MASK_ON (MASKREG_M3|MASKREG_M2|MASKREG_M1|MASKREG_M0) #define MASK_OFF (MASKREG_M3|MASKREG_M2|MASKREG_M1) @@ -279,10 +278,11 @@ typedef struct acornscsi_hostdata { struct Scsi_Host *host; /* host */ struct scsi_cmnd *SCpnt; /* currently processing command */ struct scsi_cmnd *origSCpnt; /* original connecting command */ + void __iomem *base; /* memc base address */ + void __iomem *fast; /* fast ioc base address */ /* driver information */ struct { - unsigned int io_port; /* base address of WD33C93 */ unsigned int irq; /* interrupt */ phase_t phase; /* current phase */ @@ -329,8 +329,6 @@ typedef struct acornscsi_hostdata { /* DMA info */ struct { - unsigned int io_port; /* base address of DMA controller */ - unsigned int io_intr_clear; /* address of DMA interrupt clear */ unsigned int free_addr; /* next free address */ unsigned int start_addr; /* start address of current transfer */ dmadir_t direction; /* dma direction */ @@ -345,9 +343,6 @@ typedef struct acornscsi_hostdata { /* card info */ struct { - unsigned int io_intr; /* base address of interrupt id reg */ - unsigned int io_page; /* base address of page reg */ - unsigned int io_ram; /* base address of RAM access */ unsigned char page_reg; /* current setting of page reg */ } card; -- cgit v1.2.3