diff options
| author | Geert Uytterhoeven <geert@linux-m68k.org> | 2009-08-16 05:17:35 -0400 |
|---|---|---|
| committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2010-05-26 13:51:08 -0400 |
| commit | c1d288a58936cd0654844d807e53a203f4838fb4 (patch) | |
| tree | e7ce5af31547f2d2e0e2d60a9377fc4710ef5aa1 /drivers | |
| parent | 65c2784a24d8d0a67ba3a50029846e0b82bdc223 (diff) | |
m68k: amiga - GVP Series II SCSI zorro_driver conversion
Acked-by: James Bottomley <James.Bottomley@suse.de>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/scsi/gvp11.c | 298 | ||||
| -rw-r--r-- | drivers/scsi/gvp11.h | 7 |
2 files changed, 156 insertions, 149 deletions
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 874cbee1be23..4507a16ee1c6 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c | |||
| @@ -1,26 +1,20 @@ | |||
| 1 | #include <linux/types.h> | 1 | #include <linux/types.h> |
| 2 | #include <linux/mm.h> | ||
| 3 | #include <linux/slab.h> | ||
| 4 | #include <linux/blkdev.h> | ||
| 5 | #include <linux/init.h> | 2 | #include <linux/init.h> |
| 6 | #include <linux/interrupt.h> | 3 | #include <linux/interrupt.h> |
| 4 | #include <linux/mm.h> | ||
| 5 | #include <linux/slab.h> | ||
| 6 | #include <linux/spinlock.h> | ||
| 7 | #include <linux/zorro.h> | ||
| 7 | 8 | ||
| 8 | #include <asm/setup.h> | ||
| 9 | #include <asm/page.h> | 9 | #include <asm/page.h> |
| 10 | #include <asm/pgtable.h> | 10 | #include <asm/pgtable.h> |
| 11 | #include <asm/amigaints.h> | 11 | #include <asm/amigaints.h> |
| 12 | #include <asm/amigahw.h> | 12 | #include <asm/amigahw.h> |
| 13 | #include <linux/zorro.h> | ||
| 14 | #include <asm/irq.h> | ||
| 15 | #include <linux/spinlock.h> | ||
| 16 | 13 | ||
| 17 | #include "scsi.h" | 14 | #include "scsi.h" |
| 18 | #include <scsi/scsi_host.h> | ||
| 19 | #include "wd33c93.h" | 15 | #include "wd33c93.h" |
| 20 | #include "gvp11.h" | 16 | #include "gvp11.h" |
| 21 | 17 | ||
| 22 | #include <linux/stat.h> | ||
| 23 | |||
| 24 | 18 | ||
| 25 | #define CHECK_WD33C93 | 19 | #define CHECK_WD33C93 |
| 26 | 20 | ||
| @@ -169,7 +163,40 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, | |||
| 169 | } | 163 | } |
| 170 | } | 164 | } |
| 171 | 165 | ||
| 172 | static int __init check_wd33c93(struct gvp11_scsiregs *regs) | 166 | static int gvp11_bus_reset(struct scsi_cmnd *cmd) |
| 167 | { | ||
| 168 | struct Scsi_Host *instance = cmd->device->host; | ||
| 169 | |||
| 170 | /* FIXME perform bus-specific reset */ | ||
| 171 | |||
| 172 | /* FIXME 2: shouldn't we no-op this function (return | ||
| 173 | FAILED), and fall back to host reset function, | ||
| 174 | wd33c93_host_reset ? */ | ||
| 175 | |||
| 176 | spin_lock_irq(instance->host_lock); | ||
| 177 | wd33c93_host_reset(cmd); | ||
| 178 | spin_unlock_irq(instance->host_lock); | ||
| 179 | |||
| 180 | return SUCCESS; | ||
| 181 | } | ||
| 182 | |||
| 183 | static struct scsi_host_template gvp11_scsi_template = { | ||
| 184 | .module = THIS_MODULE, | ||
| 185 | .name = "GVP Series II SCSI", | ||
| 186 | .proc_info = wd33c93_proc_info, | ||
| 187 | .proc_name = "GVP11", | ||
| 188 | .queuecommand = wd33c93_queuecommand, | ||
| 189 | .eh_abort_handler = wd33c93_abort, | ||
| 190 | .eh_bus_reset_handler = gvp11_bus_reset, | ||
| 191 | .eh_host_reset_handler = wd33c93_host_reset, | ||
| 192 | .can_queue = CAN_QUEUE, | ||
| 193 | .this_id = 7, | ||
| 194 | .sg_tablesize = SG_ALL, | ||
| 195 | .cmd_per_lun = CMD_PER_LUN, | ||
| 196 | .use_clustering = DISABLE_CLUSTERING | ||
| 197 | }; | ||
| 198 | |||
| 199 | static int __devinit check_wd33c93(struct gvp11_scsiregs *regs) | ||
| 173 | { | 200 | { |
| 174 | #ifdef CHECK_WD33C93 | 201 | #ifdef CHECK_WD33C93 |
| 175 | volatile unsigned char *sasr_3393, *scmd_3393; | 202 | volatile unsigned char *sasr_3393, *scmd_3393; |
| @@ -249,163 +276,150 @@ static int __init check_wd33c93(struct gvp11_scsiregs *regs) | |||
| 249 | return 0; | 276 | return 0; |
| 250 | } | 277 | } |
| 251 | 278 | ||
| 252 | int __init gvp11_detect(struct scsi_host_template *tpnt) | 279 | static int __devinit gvp11_probe(struct zorro_dev *z, |
| 280 | const struct zorro_device_id *ent) | ||
| 253 | { | 281 | { |
| 254 | static unsigned char called = 0; | ||
| 255 | struct Scsi_Host *instance; | 282 | struct Scsi_Host *instance; |
| 256 | unsigned long address; | 283 | unsigned long address; |
| 284 | int error; | ||
| 257 | unsigned int epc; | 285 | unsigned int epc; |
| 258 | struct zorro_dev *z = NULL; | ||
| 259 | unsigned int default_dma_xfer_mask; | 286 | unsigned int default_dma_xfer_mask; |
| 260 | struct WD33C93_hostdata *hdata; | 287 | struct WD33C93_hostdata *hdata; |
| 261 | struct gvp11_scsiregs *regs; | 288 | struct gvp11_scsiregs *regs; |
| 262 | wd33c93_regs wdregs; | 289 | wd33c93_regs wdregs; |
| 263 | int num_gvp11 = 0; | 290 | |
| 264 | 291 | default_dma_xfer_mask = ent->driver_data; | |
| 265 | if (!MACH_IS_AMIGA || called) | 292 | |
| 266 | return 0; | 293 | /* |
| 267 | called = 1; | 294 | * Rumors state that some GVP ram boards use the same product |
| 268 | 295 | * code as the SCSI controllers. Therefore if the board-size | |
| 269 | tpnt->proc_name = "GVP11"; | 296 | * is not 64KB we asume it is a ram board and bail out. |
| 270 | tpnt->proc_info = &wd33c93_proc_info; | 297 | */ |
| 271 | 298 | if (zorro_resource_len(z) != 0x10000) | |
| 272 | while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { | 299 | return -ENODEV; |
| 273 | /* | 300 | |
| 274 | * This should (hopefully) be the correct way to identify | 301 | address = z->resource.start; |
| 275 | * all the different GVP SCSI controllers (except for the | 302 | if (!request_mem_region(address, 256, "wd33c93")) |
| 276 | * SERIES I though). | 303 | return -EBUSY; |
| 277 | */ | 304 | |
| 278 | 305 | regs = (struct gvp11_scsiregs *)(ZTWO_VADDR(address)); | |
| 279 | if (z->id == ZORRO_PROD_GVP_COMBO_030_R3_SCSI || | 306 | |
| 280 | z->id == ZORRO_PROD_GVP_SERIES_II) | 307 | error = check_wd33c93(regs); |
| 281 | default_dma_xfer_mask = ~0x00ffffff; | 308 | if (error) |
| 282 | else if (z->id == ZORRO_PROD_GVP_GFORCE_030_SCSI || | 309 | goto fail_check_or_alloc; |
| 283 | z->id == ZORRO_PROD_GVP_A530_SCSI || | 310 | |
| 284 | z->id == ZORRO_PROD_GVP_COMBO_030_R4_SCSI) | 311 | instance = scsi_host_alloc(&gvp11_scsi_template, |
| 285 | default_dma_xfer_mask = ~0x01ffffff; | 312 | sizeof(struct WD33C93_hostdata)); |
| 286 | else if (z->id == ZORRO_PROD_GVP_A1291 || | 313 | if (!instance) { |
| 287 | z->id == ZORRO_PROD_GVP_GFORCE_040_SCSI_1) | 314 | error = -ENOMEM; |
| 288 | default_dma_xfer_mask = ~0x07ffffff; | 315 | goto fail_check_or_alloc; |
| 289 | else | ||
| 290 | continue; | ||
| 291 | |||
| 292 | /* | ||
| 293 | * Rumors state that some GVP ram boards use the same product | ||
| 294 | * code as the SCSI controllers. Therefore if the board-size | ||
| 295 | * is not 64KB we asume it is a ram board and bail out. | ||
| 296 | */ | ||
| 297 | if (z->resource.end - z->resource.start != 0xffff) | ||
| 298 | continue; | ||
| 299 | |||
| 300 | address = z->resource.start; | ||
| 301 | if (!request_mem_region(address, 256, "wd33c93")) | ||
| 302 | continue; | ||
| 303 | |||
| 304 | regs = (struct gvp11_scsiregs *)(ZTWO_VADDR(address)); | ||
| 305 | if (check_wd33c93(regs)) | ||
| 306 | goto release; | ||
| 307 | |||
| 308 | instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); | ||
| 309 | if (instance == NULL) | ||
| 310 | goto release; | ||
| 311 | instance->base = ZTWO_VADDR(address); | ||
| 312 | instance->irq = IRQ_AMIGA_PORTS; | ||
| 313 | instance->unique_id = z->slotaddr; | ||
| 314 | |||
| 315 | hdata = shost_priv(instance); | ||
| 316 | if (gvp11_xfer_mask) | ||
| 317 | hdata->dma_xfer_mask = gvp11_xfer_mask; | ||
| 318 | else | ||
| 319 | hdata->dma_xfer_mask = default_dma_xfer_mask; | ||
| 320 | |||
| 321 | regs->secret2 = 1; | ||
| 322 | regs->secret1 = 0; | ||
| 323 | regs->secret3 = 15; | ||
| 324 | while (regs->CNTR & GVP11_DMAC_BUSY) | ||
| 325 | ; | ||
| 326 | regs->CNTR = 0; | ||
| 327 | |||
| 328 | regs->BANK = 0; | ||
| 329 | |||
| 330 | epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000); | ||
| 331 | |||
| 332 | /* | ||
| 333 | * Check for 14MHz SCSI clock | ||
| 334 | */ | ||
| 335 | wdregs.SASR = ®s->SASR; | ||
| 336 | wdregs.SCMD = ®s->SCMD; | ||
| 337 | hdata->no_sync = 0xff; | ||
| 338 | hdata->fast = 0; | ||
| 339 | hdata->dma_mode = CTRL_DMA; | ||
| 340 | wd33c93_init(instance, wdregs, dma_setup, dma_stop, | ||
| 341 | (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10 | ||
| 342 | : WD33C93_FS_12_15); | ||
| 343 | |||
| 344 | if (request_irq(IRQ_AMIGA_PORTS, gvp11_intr, IRQF_SHARED, | ||
| 345 | "GVP11 SCSI", instance)) | ||
| 346 | goto unregister; | ||
| 347 | regs->CNTR = GVP11_DMAC_INT_ENABLE; | ||
| 348 | num_gvp11++; | ||
| 349 | continue; | ||
| 350 | |||
| 351 | unregister: | ||
| 352 | scsi_unregister(instance); | ||
| 353 | release: | ||
| 354 | release_mem_region(address, 256); | ||
| 355 | } | 316 | } |
| 356 | 317 | ||
| 357 | return num_gvp11; | 318 | instance->base = (unsigned long)regs; |
| 358 | } | 319 | instance->irq = IRQ_AMIGA_PORTS; |
| 320 | instance->unique_id = z->slotaddr; | ||
| 359 | 321 | ||
| 360 | static int gvp11_bus_reset(struct scsi_cmnd *cmd) | 322 | regs->secret2 = 1; |
| 361 | { | 323 | regs->secret1 = 0; |
| 362 | /* FIXME perform bus-specific reset */ | 324 | regs->secret3 = 15; |
| 325 | while (regs->CNTR & GVP11_DMAC_BUSY) | ||
| 326 | ; | ||
| 327 | regs->CNTR = 0; | ||
| 328 | regs->BANK = 0; | ||
| 363 | 329 | ||
| 364 | /* FIXME 2: shouldn't we no-op this function (return | 330 | wdregs.SASR = ®s->SASR; |
| 365 | FAILED), and fall back to host reset function, | 331 | wdregs.SCMD = ®s->SCMD; |
| 366 | wd33c93_host_reset ? */ | ||
| 367 | 332 | ||
| 368 | spin_lock_irq(cmd->device->host->host_lock); | 333 | hdata = shost_priv(instance); |
| 369 | wd33c93_host_reset(cmd); | 334 | if (gvp11_xfer_mask) |
| 370 | spin_unlock_irq(cmd->device->host->host_lock); | 335 | hdata->dma_xfer_mask = gvp11_xfer_mask; |
| 336 | else | ||
| 337 | hdata->dma_xfer_mask = default_dma_xfer_mask; | ||
| 371 | 338 | ||
| 372 | return SUCCESS; | 339 | hdata->no_sync = 0xff; |
| 373 | } | 340 | hdata->fast = 0; |
| 341 | hdata->dma_mode = CTRL_DMA; | ||
| 374 | 342 | ||
| 343 | /* | ||
| 344 | * Check for 14MHz SCSI clock | ||
| 345 | */ | ||
| 346 | epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000); | ||
| 347 | wd33c93_init(instance, wdregs, dma_setup, dma_stop, | ||
| 348 | (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10 | ||
| 349 | : WD33C93_FS_12_15); | ||
| 375 | 350 | ||
| 376 | #define HOSTS_C | 351 | error = request_irq(IRQ_AMIGA_PORTS, gvp11_intr, IRQF_SHARED, |
| 352 | "GVP11 SCSI", instance); | ||
| 353 | if (error) | ||
| 354 | goto fail_irq; | ||
| 377 | 355 | ||
| 378 | #include "gvp11.h" | 356 | regs->CNTR = GVP11_DMAC_INT_ENABLE; |
| 379 | 357 | ||
| 380 | static struct scsi_host_template driver_template = { | 358 | error = scsi_add_host(instance, NULL); |
| 381 | .proc_name = "GVP11", | 359 | if (error) |
| 382 | .name = "GVP Series II SCSI", | 360 | goto fail_host; |
| 383 | .detect = gvp11_detect, | ||
| 384 | .release = gvp11_release, | ||
| 385 | .queuecommand = wd33c93_queuecommand, | ||
| 386 | .eh_abort_handler = wd33c93_abort, | ||
| 387 | .eh_bus_reset_handler = gvp11_bus_reset, | ||
| 388 | .eh_host_reset_handler = wd33c93_host_reset, | ||
| 389 | .can_queue = CAN_QUEUE, | ||
| 390 | .this_id = 7, | ||
| 391 | .sg_tablesize = SG_ALL, | ||
| 392 | .cmd_per_lun = CMD_PER_LUN, | ||
| 393 | .use_clustering = DISABLE_CLUSTERING | ||
| 394 | }; | ||
| 395 | 361 | ||
| 362 | zorro_set_drvdata(z, instance); | ||
| 363 | scsi_scan_host(instance); | ||
| 364 | return 0; | ||
| 396 | 365 | ||
| 397 | #include "scsi_module.c" | 366 | fail_host: |
| 367 | free_irq(IRQ_AMIGA_PORTS, instance); | ||
| 368 | fail_irq: | ||
| 369 | scsi_host_put(instance); | ||
| 370 | fail_check_or_alloc: | ||
| 371 | release_mem_region(address, 256); | ||
| 372 | return error; | ||
| 373 | } | ||
| 398 | 374 | ||
| 399 | int gvp11_release(struct Scsi_Host *instance) | 375 | static void __devexit gvp11_remove(struct zorro_dev *z) |
| 400 | { | 376 | { |
| 401 | #ifdef MODULE | 377 | struct Scsi_Host *instance = zorro_get_drvdata(z); |
| 402 | struct gvp11_scsiregs *regs = (struct gvp11_scsiregs *)(instance->base); | 378 | struct gvp11_scsiregs *regs = (struct gvp11_scsiregs *)(instance->base); |
| 403 | 379 | ||
| 404 | regs->CNTR = 0; | 380 | regs->CNTR = 0; |
| 405 | release_mem_region(ZTWO_PADDR(instance->base), 256); | 381 | scsi_remove_host(instance); |
| 406 | free_irq(IRQ_AMIGA_PORTS, instance); | 382 | free_irq(IRQ_AMIGA_PORTS, instance); |
| 407 | #endif | 383 | scsi_host_put(instance); |
| 408 | return 1; | 384 | release_mem_region(z->resource.start, 256); |
| 385 | } | ||
| 386 | |||
| 387 | /* | ||
| 388 | * This should (hopefully) be the correct way to identify | ||
| 389 | * all the different GVP SCSI controllers (except for the | ||
| 390 | * SERIES I though). | ||
| 391 | */ | ||
| 392 | |||
| 393 | static struct zorro_device_id gvp11_zorro_tbl[] __devinitdata = { | ||
| 394 | { ZORRO_PROD_GVP_COMBO_030_R3_SCSI, ~0x00ffffff }, | ||
| 395 | { ZORRO_PROD_GVP_SERIES_II, ~0x00ffffff }, | ||
| 396 | { ZORRO_PROD_GVP_GFORCE_030_SCSI, ~0x01ffffff }, | ||
| 397 | { ZORRO_PROD_GVP_A530_SCSI, ~0x01ffffff }, | ||
| 398 | { ZORRO_PROD_GVP_COMBO_030_R4_SCSI, ~0x01ffffff }, | ||
| 399 | { ZORRO_PROD_GVP_A1291, ~0x07ffffff }, | ||
| 400 | { ZORRO_PROD_GVP_GFORCE_040_SCSI_1, ~0x07ffffff }, | ||
| 401 | { 0 } | ||
| 402 | }; | ||
| 403 | MODULE_DEVICE_TABLE(zorro, gvp11_zorro_tbl); | ||
| 404 | |||
| 405 | static struct zorro_driver gvp11_driver = { | ||
| 406 | .name = "gvp11", | ||
| 407 | .id_table = gvp11_zorro_tbl, | ||
| 408 | .probe = gvp11_probe, | ||
| 409 | .remove = __devexit_p(gvp11_remove), | ||
| 410 | }; | ||
| 411 | |||
| 412 | static int __init gvp11_init(void) | ||
| 413 | { | ||
| 414 | return zorro_register_driver(&gvp11_driver); | ||
| 415 | } | ||
| 416 | module_init(gvp11_init); | ||
| 417 | |||
| 418 | static void __exit gvp11_exit(void) | ||
| 419 | { | ||
| 420 | zorro_unregister_driver(&gvp11_driver); | ||
| 409 | } | 421 | } |
| 422 | module_exit(gvp11_exit); | ||
| 410 | 423 | ||
| 424 | MODULE_DESCRIPTION("GVP Series II SCSI"); | ||
| 411 | MODULE_LICENSE("GPL"); | 425 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/scsi/gvp11.h b/drivers/scsi/gvp11.h index b27a3ee3313e..852913cde5dd 100644 --- a/drivers/scsi/gvp11.h +++ b/drivers/scsi/gvp11.h | |||
| @@ -11,9 +11,6 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| 13 | 13 | ||
| 14 | int gvp11_detect(struct scsi_host_template *); | ||
| 15 | int gvp11_release(struct Scsi_Host *); | ||
| 16 | |||
| 17 | #ifndef CMD_PER_LUN | 14 | #ifndef CMD_PER_LUN |
| 18 | #define CMD_PER_LUN 2 | 15 | #define CMD_PER_LUN 2 |
| 19 | #endif | 16 | #endif |
| @@ -22,8 +19,6 @@ int gvp11_release(struct Scsi_Host *); | |||
| 22 | #define CAN_QUEUE 16 | 19 | #define CAN_QUEUE 16 |
| 23 | #endif | 20 | #endif |
| 24 | 21 | ||
| 25 | #ifndef HOSTS_C | ||
| 26 | |||
| 27 | /* | 22 | /* |
| 28 | * if the transfer address ANDed with this results in a non-zero | 23 | * if the transfer address ANDed with this results in a non-zero |
| 29 | * result, then we can't use DMA. | 24 | * result, then we can't use DMA. |
| @@ -54,6 +49,4 @@ struct gvp11_scsiregs { | |||
| 54 | #define GVP11_DMAC_INT_ENABLE (1<<3) | 49 | #define GVP11_DMAC_INT_ENABLE (1<<3) |
| 55 | #define GVP11_DMAC_DIR_WRITE (1<<4) | 50 | #define GVP11_DMAC_DIR_WRITE (1<<4) |
| 56 | 51 | ||
| 57 | #endif /* else def HOSTS_C */ | ||
| 58 | |||
| 59 | #endif /* GVP11_H */ | 52 | #endif /* GVP11_H */ |
