aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-04-19 10:42:57 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-07-03 09:25:57 -0400
commite95a1b656a9809acd8ba8eb867ac6a7759d6180e (patch)
treecdea84aea86a675ad9a9775de735ebade69270e2
parenta796ef7035c6c5cc5726c3e4e8d71175c13828df (diff)
[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 <James.Bottomley@HansenPartnership.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--drivers/scsi/arm/acornscsi.c160
-rw-r--r--drivers/scsi/arm/acornscsi.h9
2 files changed, 75 insertions, 94 deletions
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index a2f8113c3b08..918ccf818757 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -136,9 +136,9 @@
136#include <linux/init.h> 136#include <linux/init.h>
137#include <linux/bitops.h> 137#include <linux/bitops.h>
138#include <linux/stringify.h> 138#include <linux/stringify.h>
139#include <linux/io.h>
139 140
140#include <asm/system.h> 141#include <asm/system.h>
141#include <asm/io.h>
142#include <asm/ecard.h> 142#include <asm/ecard.h>
143 143
144#include "../scsi.h" 144#include "../scsi.h"
@@ -198,35 +198,40 @@ static void acornscsi_abortcmd(AS_Host *host, unsigned char tag);
198 * Miscellaneous 198 * Miscellaneous
199 */ 199 */
200 200
201/* Offsets from MEMC base */
202#define SBIC_REGIDX 0x2000
203#define SBIC_REGVAL 0x2004
204#define DMAC_OFFSET 0x3000
205
206/* Offsets from FAST IOC base */
207#define INT_REG 0x2000
208#define PAGE_REG 0x3000
209
201static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value) 210static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value)
202{ 211{
203 __raw_writeb(reg, host->scsi.io_port); 212 writeb(reg, host->base + SBIC_REGIDX);
204 __raw_writeb(value, host->scsi.io_port + 4); 213 writeb(value, host->base + SBIC_REGVAL);
205} 214}
206 215
207#define sbic_arm_writenext(host,val) \
208 __raw_writeb((val), (host)->scsi.io_port + 4)
209
210static inline int sbic_arm_read(AS_Host *host, unsigned int reg) 216static inline int sbic_arm_read(AS_Host *host, unsigned int reg)
211{ 217{
212 if(reg == SBIC_ASR) 218 if(reg == SBIC_ASR)
213 return __raw_readl(host->scsi.io_port) & 255; 219 return readl(host->base + SBIC_REGIDX) & 255;
214 __raw_writeb(reg, host->scsi.io_port); 220 writeb(reg, host->base + SBIC_REGIDX);
215 return __raw_readl(host->scsi.io_port + 4) & 255; 221 return readl(host->base + SBIC_REGVAL) & 255;
216} 222}
217 223
218#define sbic_arm_readnext(host) \ 224#define sbic_arm_writenext(host, val) writeb((val), (host)->base + SBIC_REGVAL)
219 __raw_readb((host)->scsi.io_port + 4) 225#define sbic_arm_readnext(host) readb((host)->base + SBIC_REGVAL)
220 226
221#ifdef USE_DMAC 227#ifdef USE_DMAC
222#define dmac_read(host,reg) \ 228#define dmac_read(host,reg) \
223 inb((host)->dma.io_port + (reg)) 229 readb((host)->base + DMAC_OFFSET + ((reg) << 2))
224 230
225#define dmac_write(host,reg,value) \ 231#define dmac_write(host,reg,value) \
226 ({ outb((value), (host)->dma.io_port + (reg)); }) 232 ({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); })
227 233
228#define dmac_clearintr(host) \ 234#define dmac_clearintr(host) writeb(0, (host)->fast + INT_REG)
229 ({ outb(0, (host)->dma.io_intr_clear); })
230 235
231static inline unsigned int dmac_address(AS_Host *host) 236static inline unsigned int dmac_address(AS_Host *host)
232{ 237{
@@ -323,20 +328,20 @@ void acornscsi_resetcard(AS_Host *host)
323 328
324 /* assert reset line */ 329 /* assert reset line */
325 host->card.page_reg = 0x80; 330 host->card.page_reg = 0x80;
326 outb(host->card.page_reg, host->card.io_page); 331 writeb(host->card.page_reg, host->fast + PAGE_REG);
327 332
328 /* wait 3 cs. SCSI standard says 25ms. */ 333 /* wait 3 cs. SCSI standard says 25ms. */
329 acornscsi_csdelay(3); 334 acornscsi_csdelay(3);
330 335
331 host->card.page_reg = 0; 336 host->card.page_reg = 0;
332 outb(host->card.page_reg, host->card.io_page); 337 writeb(host->card.page_reg, host->fast + PAGE_REG);
333 338
334 /* 339 /*
335 * Should get a reset from the card 340 * Should get a reset from the card
336 */ 341 */
337 timeout = 1000; 342 timeout = 1000;
338 do { 343 do {
339 if (inb(host->card.io_intr) & 8) 344 if (readb(host->fast + INT_REG) & 8)
340 break; 345 break;
341 udelay(1); 346 udelay(1);
342 } while (--timeout); 347 } while (--timeout);
@@ -357,7 +362,7 @@ void acornscsi_resetcard(AS_Host *host)
357 */ 362 */
358 timeout = 1000; 363 timeout = 1000;
359 do { 364 do {
360 if (inb(host->card.io_intr) & 8) 365 if (readb(host->fast + INT_REG) & 8)
361 break; 366 break;
362 udelay(1); 367 udelay(1);
363 } while (--timeout); 368 } while (--timeout);
@@ -377,7 +382,7 @@ void acornscsi_resetcard(AS_Host *host)
377 sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); 382 sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
378 383
379 host->card.page_reg = 0x40; 384 host->card.page_reg = 0x40;
380 outb(host->card.page_reg, host->card.io_page); 385 writeb(host->card.page_reg, host->fast + PAGE_REG);
381 386
382 /* setup dmac - uPC71071 */ 387 /* setup dmac - uPC71071 */
383 dmac_write(host, DMAC_INIT, 0); 388 dmac_write(host, DMAC_INIT, 0);
@@ -910,13 +915,13 @@ static
910void acornscsi_data_read(AS_Host *host, char *ptr, 915void acornscsi_data_read(AS_Host *host, char *ptr,
911 unsigned int start_addr, unsigned int length) 916 unsigned int start_addr, unsigned int length)
912{ 917{
913 extern void __acornscsi_in(int port, char *buf, int len); 918 extern void __acornscsi_in(void __iomem *, char *buf, int len);
914 unsigned int page, offset, len = length; 919 unsigned int page, offset, len = length;
915 920
916 page = (start_addr >> 12); 921 page = (start_addr >> 12);
917 offset = start_addr & ((1 << 12) - 1); 922 offset = start_addr & ((1 << 12) - 1);
918 923
919 outb((page & 0x3f) | host->card.page_reg, host->card.io_page); 924 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
920 925
921 while (len > 0) { 926 while (len > 0) {
922 unsigned int this_len; 927 unsigned int this_len;
@@ -926,7 +931,7 @@ void acornscsi_data_read(AS_Host *host, char *ptr,
926 else 931 else
927 this_len = len; 932 this_len = len;
928 933
929 __acornscsi_in(host->card.io_ram + (offset << 1), ptr, this_len); 934 __acornscsi_in(host->base + (offset << 1), ptr, this_len);
930 935
931 offset += this_len; 936 offset += this_len;
932 ptr += this_len; 937 ptr += this_len;
@@ -935,10 +940,10 @@ void acornscsi_data_read(AS_Host *host, char *ptr,
935 if (offset == (1 << 12)) { 940 if (offset == (1 << 12)) {
936 offset = 0; 941 offset = 0;
937 page ++; 942 page ++;
938 outb((page & 0x3f) | host->card.page_reg, host->card.io_page); 943 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
939 } 944 }
940 } 945 }
941 outb(host->card.page_reg, host->card.io_page); 946 writeb(host->card.page_reg, host->fast + PAGE_REG);
942} 947}
943 948
944/* 949/*
@@ -955,13 +960,13 @@ static
955void acornscsi_data_write(AS_Host *host, char *ptr, 960void acornscsi_data_write(AS_Host *host, char *ptr,
956 unsigned int start_addr, unsigned int length) 961 unsigned int start_addr, unsigned int length)
957{ 962{
958 extern void __acornscsi_out(int port, char *buf, int len); 963 extern void __acornscsi_out(void __iomem *, char *buf, int len);
959 unsigned int page, offset, len = length; 964 unsigned int page, offset, len = length;
960 965
961 page = (start_addr >> 12); 966 page = (start_addr >> 12);
962 offset = start_addr & ((1 << 12) - 1); 967 offset = start_addr & ((1 << 12) - 1);
963 968
964 outb((page & 0x3f) | host->card.page_reg, host->card.io_page); 969 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
965 970
966 while (len > 0) { 971 while (len > 0) {
967 unsigned int this_len; 972 unsigned int this_len;
@@ -971,7 +976,7 @@ void acornscsi_data_write(AS_Host *host, char *ptr,
971 else 976 else
972 this_len = len; 977 this_len = len;
973 978
974 __acornscsi_out(host->card.io_ram + (offset << 1), ptr, this_len); 979 __acornscsi_out(host->base + (offset << 1), ptr, this_len);
975 980
976 offset += this_len; 981 offset += this_len;
977 ptr += this_len; 982 ptr += this_len;
@@ -980,10 +985,10 @@ void acornscsi_data_write(AS_Host *host, char *ptr,
980 if (offset == (1 << 12)) { 985 if (offset == (1 << 12)) {
981 offset = 0; 986 offset = 0;
982 page ++; 987 page ++;
983 outb((page & 0x3f) | host->card.page_reg, host->card.io_page); 988 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
984 } 989 }
985 } 990 }
986 outb(host->card.page_reg, host->card.io_page); 991 writeb(host->card.page_reg, host->fast + PAGE_REG);
987} 992}
988 993
989/* ========================================================================================= 994/* =========================================================================================
@@ -2468,11 +2473,11 @@ acornscsi_intr(int irq, void *dev_id)
2468 do { 2473 do {
2469 ret = INTR_IDLE; 2474 ret = INTR_IDLE;
2470 2475
2471 iostatus = inb(host->card.io_intr); 2476 iostatus = readb(host->fast + INT_REG);
2472 2477
2473 if (iostatus & 2) { 2478 if (iostatus & 2) {
2474 acornscsi_dma_intr(host); 2479 acornscsi_dma_intr(host);
2475 iostatus = inb(host->card.io_intr); 2480 iostatus = readb(host->fast + INT_REG);
2476 } 2481 }
2477 2482
2478 if (iostatus & 8) 2483 if (iostatus & 8)
@@ -2858,11 +2863,11 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
2858#endif 2863#endif
2859 "\n\n", VER_MAJOR, VER_MINOR, VER_PATCH); 2864 "\n\n", VER_MAJOR, VER_MINOR, VER_PATCH);
2860 2865
2861 p += sprintf(p, "SBIC: WD33C93A Address: %08X IRQ : %d\n", 2866 p += sprintf(p, "SBIC: WD33C93A Address: %p IRQ : %d\n",
2862 host->scsi.io_port, host->scsi.irq); 2867 host->base + SBIC_REGIDX, host->scsi.irq);
2863#ifdef USE_DMAC 2868#ifdef USE_DMAC
2864 p += sprintf(p, "DMAC: uPC71071 Address: %08X IRQ : %d\n\n", 2869 p += sprintf(p, "DMAC: uPC71071 Address: %p IRQ : %d\n\n",
2865 host->dma.io_port, host->scsi.irq); 2870 host->base + DMAC_OFFSET, host->scsi.irq);
2866#endif 2871#endif
2867 2872
2868 p += sprintf(p, "Statistics:\n" 2873 p += sprintf(p, "Statistics:\n"
@@ -2964,48 +2969,37 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
2964{ 2969{
2965 struct Scsi_Host *host; 2970 struct Scsi_Host *host;
2966 AS_Host *ashost; 2971 AS_Host *ashost;
2967 int ret = -ENOMEM; 2972 int ret;
2968 2973
2969 host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host)); 2974 ret = ecard_request_resources(ec);
2970 if (!host) 2975 if (ret)
2971 goto out; 2976 goto out;
2972 2977
2978 host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
2979 if (!host) {
2980 ret = -ENOMEM;
2981 goto out_release;
2982 }
2983
2973 ashost = (AS_Host *)host->hostdata; 2984 ashost = (AS_Host *)host->hostdata;
2974 2985
2975 host->io_port = ecard_address(ec, ECARD_MEMC, 0); 2986 ashost->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
2976 host->irq = ec->irq; 2987 ashost->fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
2988 if (!ashost->base || !ashost->fast)
2989 goto out_put;
2977 2990
2978 ashost->host = host; 2991 host->irq = ec->irq;
2979 ashost->scsi.io_port = ioaddr(host->io_port + 0x800); 2992 ashost->host = host;
2980 ashost->scsi.irq = host->irq; 2993 ashost->scsi.irq = host->irq;
2981 ashost->card.io_intr = POD_SPACE(host->io_port) + 0x800;
2982 ashost->card.io_page = POD_SPACE(host->io_port) + 0xc00;
2983 ashost->card.io_ram = ioaddr(host->io_port);
2984 ashost->dma.io_port = host->io_port + 0xc00;
2985 ashost->dma.io_intr_clear = POD_SPACE(host->io_port) + 0x800;
2986 2994
2987 ec->irqaddr = (char *)ioaddr(ashost->card.io_intr); 2995 ec->irqaddr = ashost->fast + INT_REG;
2988 ec->irqmask = 0x0a; 2996 ec->irqmask = 0x0a;
2989 2997
2990 ret = -EBUSY;
2991 if (!request_region(host->io_port + 0x800, 2, "acornscsi(sbic)"))
2992 goto err_1;
2993 if (!request_region(ashost->card.io_intr, 1, "acornscsi(intr)"))
2994 goto err_2;
2995 if (!request_region(ashost->card.io_page, 1, "acornscsi(page)"))
2996 goto err_3;
2997#ifdef USE_DMAC
2998 if (!request_region(ashost->dma.io_port, 256, "acornscsi(dmac)"))
2999 goto err_4;
3000#endif
3001 if (!request_region(host->io_port, 2048, "acornscsi(ram)"))
3002 goto err_5;
3003
3004 ret = request_irq(host->irq, acornscsi_intr, IRQF_DISABLED, "acornscsi", ashost); 2998 ret = request_irq(host->irq, acornscsi_intr, IRQF_DISABLED, "acornscsi", ashost);
3005 if (ret) { 2999 if (ret) {
3006 printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n", 3000 printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n",
3007 host->host_no, ashost->scsi.irq, ret); 3001 host->host_no, ashost->scsi.irq, ret);
3008 goto err_6; 3002 goto out_put;
3009 } 3003 }
3010 3004
3011 memset(&ashost->stats, 0, sizeof (ashost->stats)); 3005 memset(&ashost->stats, 0, sizeof (ashost->stats));
@@ -3017,27 +3011,22 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
3017 3011
3018 ret = scsi_add_host(host, &ec->dev); 3012 ret = scsi_add_host(host, &ec->dev);
3019 if (ret) 3013 if (ret)
3020 goto err_7; 3014 goto out_irq;
3021 3015
3022 scsi_scan_host(host); 3016 scsi_scan_host(host);
3023 goto out; 3017 goto out;
3024 3018
3025 err_7: 3019 out_irq:
3026 free_irq(host->irq, ashost); 3020 free_irq(host->irq, ashost);
3027 err_6: 3021 msgqueue_free(&ashost->scsi.msgs);
3028 release_region(host->io_port, 2048); 3022 queue_free(&ashost->queues.disconnected);
3029 err_5: 3023 queue_free(&ashost->queues.issue);
3030#ifdef USE_DMAC 3024 out_put:
3031 release_region(ashost->dma.io_port, 256); 3025 ecardm_iounmap(ec, ashost->fast);
3032#endif 3026 ecardm_iounmap(ec, ashost->base);
3033 err_4:
3034 release_region(ashost->card.io_page, 1);
3035 err_3:
3036 release_region(ashost->card.io_intr, 1);
3037 err_2:
3038 release_region(host->io_port + 0x800, 2);
3039 err_1:
3040 scsi_host_put(host); 3027 scsi_host_put(host);
3028 out_release:
3029 ecard_release_resources(ec);
3041 out: 3030 out:
3042 return ret; 3031 return ret;
3043} 3032}
@@ -3053,20 +3042,17 @@ static void __devexit acornscsi_remove(struct expansion_card *ec)
3053 /* 3042 /*
3054 * Put card into RESET state 3043 * Put card into RESET state
3055 */ 3044 */
3056 outb(0x80, ashost->card.io_page); 3045 writeb(0x80, ashost->fast + PAGE_REG);
3057 3046
3058 free_irq(host->irq, ashost); 3047 free_irq(host->irq, ashost);
3059 3048
3060 release_region(host->io_port + 0x800, 2);
3061 release_region(ashost->card.io_intr, 1);
3062 release_region(ashost->card.io_page, 1);
3063 release_region(ashost->dma.io_port, 256);
3064 release_region(host->io_port, 2048);
3065
3066 msgqueue_free(&ashost->scsi.msgs); 3049 msgqueue_free(&ashost->scsi.msgs);
3067 queue_free(&ashost->queues.disconnected); 3050 queue_free(&ashost->queues.disconnected);
3068 queue_free(&ashost->queues.issue); 3051 queue_free(&ashost->queues.issue);
3052 ecardm_iounmap(ec, ashost->fast);
3053 ecardm_iounmap(ec, ashost->base);
3069 scsi_host_put(host); 3054 scsi_host_put(host);
3055 ecard_release_resources(ec);
3070} 3056}
3071 3057
3072static const struct ecard_id acornscsi_cids[] = { 3058static const struct ecard_id acornscsi_cids[] = {
diff --git a/drivers/scsi/arm/acornscsi.h b/drivers/scsi/arm/acornscsi.h
index d11424b89f42..8d2172a0b351 100644
--- a/drivers/scsi/arm/acornscsi.h
+++ b/drivers/scsi/arm/acornscsi.h
@@ -179,7 +179,6 @@
179 179
180/* miscellaneous internal variables */ 180/* miscellaneous internal variables */
181 181
182#define POD_SPACE(x) ((x) + 0xd0000)
183#define MASK_ON (MASKREG_M3|MASKREG_M2|MASKREG_M1|MASKREG_M0) 182#define MASK_ON (MASKREG_M3|MASKREG_M2|MASKREG_M1|MASKREG_M0)
184#define MASK_OFF (MASKREG_M3|MASKREG_M2|MASKREG_M1) 183#define MASK_OFF (MASKREG_M3|MASKREG_M2|MASKREG_M1)
185 184
@@ -279,10 +278,11 @@ typedef struct acornscsi_hostdata {
279 struct Scsi_Host *host; /* host */ 278 struct Scsi_Host *host; /* host */
280 struct scsi_cmnd *SCpnt; /* currently processing command */ 279 struct scsi_cmnd *SCpnt; /* currently processing command */
281 struct scsi_cmnd *origSCpnt; /* original connecting command */ 280 struct scsi_cmnd *origSCpnt; /* original connecting command */
281 void __iomem *base; /* memc base address */
282 void __iomem *fast; /* fast ioc base address */
282 283
283 /* driver information */ 284 /* driver information */
284 struct { 285 struct {
285 unsigned int io_port; /* base address of WD33C93 */
286 unsigned int irq; /* interrupt */ 286 unsigned int irq; /* interrupt */
287 phase_t phase; /* current phase */ 287 phase_t phase; /* current phase */
288 288
@@ -329,8 +329,6 @@ typedef struct acornscsi_hostdata {
329 329
330 /* DMA info */ 330 /* DMA info */
331 struct { 331 struct {
332 unsigned int io_port; /* base address of DMA controller */
333 unsigned int io_intr_clear; /* address of DMA interrupt clear */
334 unsigned int free_addr; /* next free address */ 332 unsigned int free_addr; /* next free address */
335 unsigned int start_addr; /* start address of current transfer */ 333 unsigned int start_addr; /* start address of current transfer */
336 dmadir_t direction; /* dma direction */ 334 dmadir_t direction; /* dma direction */
@@ -345,9 +343,6 @@ typedef struct acornscsi_hostdata {
345 343
346 /* card info */ 344 /* card info */
347 struct { 345 struct {
348 unsigned int io_intr; /* base address of interrupt id reg */
349 unsigned int io_page; /* base address of page reg */
350 unsigned int io_ram; /* base address of RAM access */
351 unsigned char page_reg; /* current setting of page reg */ 346 unsigned char page_reg; /* current setting of page reg */
352 } card; 347 } card;
353 348