Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Oktagon_esp.c -- Driver for bsc Oktagon |
| 3 | * |
| 4 | * Written by Carsten Pluntke 1998 |
| 5 | * |
| 6 | * Based on cyber_esp.c |
| 7 | */ |
| 8 | |
| 9 | #include <linux/config.h> |
| 10 | |
| 11 | #if defined(CONFIG_AMIGA) || defined(CONFIG_APUS) |
| 12 | #define USE_BOTTOM_HALF |
| 13 | #endif |
| 14 | |
| 15 | #include <linux/module.h> |
| 16 | |
| 17 | #include <linux/kernel.h> |
| 18 | #include <linux/delay.h> |
| 19 | #include <linux/types.h> |
| 20 | #include <linux/string.h> |
| 21 | #include <linux/slab.h> |
| 22 | #include <linux/blkdev.h> |
| 23 | #include <linux/proc_fs.h> |
| 24 | #include <linux/stat.h> |
| 25 | #include <linux/reboot.h> |
| 26 | #include <asm/system.h> |
| 27 | #include <asm/ptrace.h> |
| 28 | #include <asm/pgtable.h> |
| 29 | |
| 30 | |
| 31 | #include "scsi.h" |
| 32 | #include <scsi/scsi_host.h> |
| 33 | #include "NCR53C9x.h" |
| 34 | |
| 35 | #include <linux/zorro.h> |
| 36 | #include <asm/irq.h> |
| 37 | #include <asm/amigaints.h> |
| 38 | #include <asm/amigahw.h> |
| 39 | |
| 40 | #ifdef USE_BOTTOM_HALF |
| 41 | #include <linux/workqueue.h> |
| 42 | #include <linux/interrupt.h> |
| 43 | #endif |
| 44 | |
| 45 | /* The controller registers can be found in the Z2 config area at these |
| 46 | * offsets: |
| 47 | */ |
| 48 | #define OKTAGON_ESP_ADDR 0x03000 |
| 49 | #define OKTAGON_DMA_ADDR 0x01000 |
| 50 | |
| 51 | |
| 52 | static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); |
| 53 | static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp); |
| 54 | static void dma_dump_state(struct NCR_ESP *esp); |
| 55 | static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); |
| 56 | static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); |
| 57 | static void dma_ints_off(struct NCR_ESP *esp); |
| 58 | static void dma_ints_on(struct NCR_ESP *esp); |
| 59 | static int dma_irq_p(struct NCR_ESP *esp); |
| 60 | static void dma_led_off(struct NCR_ESP *esp); |
| 61 | static void dma_led_on(struct NCR_ESP *esp); |
| 62 | static int dma_ports_p(struct NCR_ESP *esp); |
| 63 | static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); |
| 64 | |
| 65 | static void dma_irq_exit(struct NCR_ESP *esp); |
| 66 | static void dma_invalidate(struct NCR_ESP *esp); |
| 67 | |
| 68 | static void dma_mmu_get_scsi_one(struct NCR_ESP *,Scsi_Cmnd *); |
| 69 | static void dma_mmu_get_scsi_sgl(struct NCR_ESP *,Scsi_Cmnd *); |
| 70 | static void dma_mmu_release_scsi_one(struct NCR_ESP *,Scsi_Cmnd *); |
| 71 | static void dma_mmu_release_scsi_sgl(struct NCR_ESP *,Scsi_Cmnd *); |
| 72 | static void dma_advance_sg(Scsi_Cmnd *); |
| 73 | static int oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x); |
| 74 | |
| 75 | #ifdef USE_BOTTOM_HALF |
| 76 | static void dma_commit(void *opaque); |
| 77 | |
| 78 | long oktag_to_io(long *paddr, long *addr, long len); |
| 79 | long oktag_from_io(long *addr, long *paddr, long len); |
| 80 | |
| 81 | static DECLARE_WORK(tq_fake_dma, dma_commit, NULL); |
| 82 | |
| 83 | #define DMA_MAXTRANSFER 0x8000 |
| 84 | |
| 85 | #else |
| 86 | |
| 87 | /* |
| 88 | * No bottom half. Use transfer directly from IRQ. Find a narrow path |
| 89 | * between too much IRQ overhead and clogging the IRQ for too long. |
| 90 | */ |
| 91 | |
| 92 | #define DMA_MAXTRANSFER 0x1000 |
| 93 | |
| 94 | #endif |
| 95 | |
| 96 | static struct notifier_block oktagon_notifier = { |
| 97 | oktagon_notify_reboot, |
| 98 | NULL, |
| 99 | 0 |
| 100 | }; |
| 101 | |
| 102 | static long *paddress; |
| 103 | static long *address; |
| 104 | static long len; |
| 105 | static long dma_on; |
| 106 | static int direction; |
| 107 | static struct NCR_ESP *current_esp; |
| 108 | |
| 109 | |
| 110 | static volatile unsigned char cmd_buffer[16]; |
| 111 | /* This is where all commands are put |
| 112 | * before they are trasfered to the ESP chip |
| 113 | * via PIO. |
| 114 | */ |
| 115 | |
| 116 | /***************************************************************** Detection */ |
Christoph Hellwig | d0be4a7d | 2005-10-31 18:31:40 +0100 | [diff] [blame] | 117 | int oktagon_esp_detect(struct scsi_host_template *tpnt) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 118 | { |
| 119 | struct NCR_ESP *esp; |
| 120 | struct zorro_dev *z = NULL; |
| 121 | unsigned long address; |
| 122 | struct ESP_regs *eregs; |
| 123 | |
| 124 | while ((z = zorro_find_device(ZORRO_PROD_BSC_OKTAGON_2008, z))) { |
| 125 | unsigned long board = z->resource.start; |
| 126 | if (request_mem_region(board+OKTAGON_ESP_ADDR, |
| 127 | sizeof(struct ESP_regs), "NCR53C9x")) { |
| 128 | /* |
| 129 | * It is a SCSI controller. |
| 130 | * Hardwire Host adapter to SCSI ID 7 |
| 131 | */ |
| 132 | |
| 133 | address = (unsigned long)ZTWO_VADDR(board); |
| 134 | eregs = (struct ESP_regs *)(address + OKTAGON_ESP_ADDR); |
| 135 | |
| 136 | /* This line was 5 lines lower */ |
| 137 | esp = esp_allocate(tpnt, (void *)board+OKTAGON_ESP_ADDR); |
| 138 | |
| 139 | /* we have to shift the registers only one bit for oktagon */ |
| 140 | esp->shift = 1; |
| 141 | |
| 142 | esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7)); |
| 143 | udelay(5); |
| 144 | if (esp_read(eregs->esp_cfg1) != (ESP_CONFIG1_PENABLE | 7)) |
| 145 | return 0; /* Bail out if address did not hold data */ |
| 146 | |
| 147 | /* Do command transfer with programmed I/O */ |
| 148 | esp->do_pio_cmds = 1; |
| 149 | |
| 150 | /* Required functions */ |
| 151 | esp->dma_bytes_sent = &dma_bytes_sent; |
| 152 | esp->dma_can_transfer = &dma_can_transfer; |
| 153 | esp->dma_dump_state = &dma_dump_state; |
| 154 | esp->dma_init_read = &dma_init_read; |
| 155 | esp->dma_init_write = &dma_init_write; |
| 156 | esp->dma_ints_off = &dma_ints_off; |
| 157 | esp->dma_ints_on = &dma_ints_on; |
| 158 | esp->dma_irq_p = &dma_irq_p; |
| 159 | esp->dma_ports_p = &dma_ports_p; |
| 160 | esp->dma_setup = &dma_setup; |
| 161 | |
| 162 | /* Optional functions */ |
| 163 | esp->dma_barrier = 0; |
| 164 | esp->dma_drain = 0; |
| 165 | esp->dma_invalidate = &dma_invalidate; |
| 166 | esp->dma_irq_entry = 0; |
| 167 | esp->dma_irq_exit = &dma_irq_exit; |
| 168 | esp->dma_led_on = &dma_led_on; |
| 169 | esp->dma_led_off = &dma_led_off; |
| 170 | esp->dma_poll = 0; |
| 171 | esp->dma_reset = 0; |
| 172 | |
| 173 | esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one; |
| 174 | esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl; |
| 175 | esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one; |
| 176 | esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl; |
| 177 | esp->dma_advance_sg = &dma_advance_sg; |
| 178 | |
| 179 | /* SCSI chip speed */ |
| 180 | /* Looking at the quartz of the SCSI board... */ |
| 181 | esp->cfreq = 25000000; |
| 182 | |
| 183 | /* The DMA registers on the CyberStorm are mapped |
| 184 | * relative to the device (i.e. in the same Zorro |
| 185 | * I/O block). |
| 186 | */ |
| 187 | esp->dregs = (void *)(address + OKTAGON_DMA_ADDR); |
| 188 | |
| 189 | paddress = (long *) esp->dregs; |
| 190 | |
| 191 | /* ESP register base */ |
| 192 | esp->eregs = eregs; |
| 193 | |
| 194 | /* Set the command buffer */ |
| 195 | esp->esp_command = (volatile unsigned char*) cmd_buffer; |
| 196 | |
| 197 | /* Yes, the virtual address. See below. */ |
| 198 | esp->esp_command_dvma = (__u32) cmd_buffer; |
| 199 | |
| 200 | esp->irq = IRQ_AMIGA_PORTS; |
| 201 | request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, |
| 202 | "BSC Oktagon SCSI", esp->ehost); |
| 203 | |
| 204 | /* Figure out our scsi ID on the bus */ |
| 205 | esp->scsi_id = 7; |
| 206 | |
| 207 | /* We don't have a differential SCSI-bus. */ |
| 208 | esp->diff = 0; |
| 209 | |
| 210 | esp_initialize(esp); |
| 211 | |
| 212 | printk("ESP_Oktagon Driver 1.1" |
| 213 | #ifdef USE_BOTTOM_HALF |
| 214 | " [BOTTOM_HALF]" |
| 215 | #else |
| 216 | " [IRQ]" |
| 217 | #endif |
| 218 | " registered.\n"); |
| 219 | printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use); |
| 220 | esps_running = esps_in_use; |
| 221 | current_esp = esp; |
| 222 | register_reboot_notifier(&oktagon_notifier); |
| 223 | return esps_in_use; |
| 224 | } |
| 225 | } |
| 226 | return 0; |
| 227 | } |
| 228 | |
| 229 | |
| 230 | /* |
| 231 | * On certain configurations the SCSI equipment gets confused on reboot, |
| 232 | * so we have to reset it then. |
| 233 | */ |
| 234 | |
| 235 | static int |
| 236 | oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x) |
| 237 | { |
| 238 | struct NCR_ESP *esp; |
| 239 | |
| 240 | if((code == SYS_DOWN || code == SYS_HALT) && (esp = current_esp)) |
| 241 | { |
| 242 | esp_bootup_reset(esp,esp->eregs); |
| 243 | udelay(500); /* Settle time. Maybe unnecessary. */ |
| 244 | } |
| 245 | return NOTIFY_DONE; |
| 246 | } |
| 247 | |
| 248 | |
| 249 | |
| 250 | #ifdef USE_BOTTOM_HALF |
| 251 | |
| 252 | |
| 253 | /* |
| 254 | * The bsc Oktagon controller has no real DMA, so we have to do the 'DMA |
| 255 | * transfer' in the interrupt (Yikes!) or use a bottom half to not to clutter |
| 256 | * IRQ's for longer-than-good. |
| 257 | * |
| 258 | * FIXME |
| 259 | * BIG PROBLEM: 'len' is usually the buffer length, not the expected length |
| 260 | * of the data. So DMA may finish prematurely, further reads lead to |
| 261 | * 'machine check' on APUS systems (don't know about m68k systems, AmigaOS |
| 262 | * deliberately ignores the bus faults) and a normal copy-loop can't |
| 263 | * be exited prematurely just at the right moment by the dma_invalidate IRQ. |
| 264 | * So do it the hard way, write an own copier in assembler and |
| 265 | * catch the exception. |
| 266 | * -- Carsten |
| 267 | */ |
| 268 | |
| 269 | |
| 270 | static void dma_commit(void *opaque) |
| 271 | { |
| 272 | long wait,len2,pos; |
| 273 | struct NCR_ESP *esp; |
| 274 | |
| 275 | ESPDATA(("Transfer: %ld bytes, Address 0x%08lX, Direction: %d\n", |
| 276 | len,(long) address,direction)); |
| 277 | dma_ints_off(current_esp); |
| 278 | |
| 279 | pos = 0; |
| 280 | wait = 1; |
| 281 | if(direction) /* write? (memory to device) */ |
| 282 | { |
| 283 | while(len > 0) |
| 284 | { |
| 285 | len2 = oktag_to_io(paddress, address+pos, len); |
| 286 | if(!len2) |
| 287 | { |
| 288 | if(wait > 1000) |
| 289 | { |
| 290 | printk("Expedited DMA exit (writing) %ld\n",len); |
| 291 | break; |
| 292 | } |
| 293 | mdelay(wait); |
| 294 | wait *= 2; |
| 295 | } |
| 296 | pos += len2; |
| 297 | len -= len2*sizeof(long); |
| 298 | } |
| 299 | } else { |
| 300 | while(len > 0) |
| 301 | { |
| 302 | len2 = oktag_from_io(address+pos, paddress, len); |
| 303 | if(!len2) |
| 304 | { |
| 305 | if(wait > 1000) |
| 306 | { |
| 307 | printk("Expedited DMA exit (reading) %ld\n",len); |
| 308 | break; |
| 309 | } |
| 310 | mdelay(wait); |
| 311 | wait *= 2; |
| 312 | } |
| 313 | pos += len2; |
| 314 | len -= len2*sizeof(long); |
| 315 | } |
| 316 | } |
| 317 | |
| 318 | /* to make esp->shift work */ |
| 319 | esp=current_esp; |
| 320 | |
| 321 | #if 0 |
| 322 | len2 = (esp_read(current_esp->eregs->esp_tclow) & 0xff) | |
| 323 | ((esp_read(current_esp->eregs->esp_tcmed) & 0xff) << 8); |
| 324 | |
| 325 | /* |
| 326 | * Uh uh. If you see this, len and transfer count registers were out of |
| 327 | * sync. That means really serious trouble. |
| 328 | */ |
| 329 | |
| 330 | if(len2) |
| 331 | printk("Eeeek!! Transfer count still %ld!\n",len2); |
| 332 | #endif |
| 333 | |
| 334 | /* |
| 335 | * Normally we just need to exit and wait for the interrupt to come. |
| 336 | * But at least one device (my Microtek ScanMaker 630) regularly mis- |
| 337 | * calculates the bytes it should send which is really ugly because |
| 338 | * it locks up the SCSI bus if not accounted for. |
| 339 | */ |
| 340 | |
| 341 | if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR)) |
| 342 | { |
| 343 | long len = 100; |
| 344 | long trash[10]; |
| 345 | |
| 346 | /* |
| 347 | * Interrupt bit was not set. Either the device is just plain lazy |
| 348 | * so we give it a 10 ms chance or... |
| 349 | */ |
| 350 | while(len-- && (!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR))) |
| 351 | udelay(100); |
| 352 | |
| 353 | |
| 354 | if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR)) |
| 355 | { |
| 356 | /* |
| 357 | * So we think that the transfer count is out of sync. Since we |
| 358 | * have all we want we are happy and can ditch the trash. |
| 359 | */ |
| 360 | |
| 361 | len = DMA_MAXTRANSFER; |
| 362 | |
| 363 | while(len-- && (!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR))) |
| 364 | oktag_from_io(trash,paddress,2); |
| 365 | |
| 366 | if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR)) |
| 367 | { |
| 368 | /* |
| 369 | * Things really have gone wrong. If we leave the system in that |
| 370 | * state, the SCSI bus is locked forever. I hope that this will |
| 371 | * turn the system in a more or less running state. |
| 372 | */ |
| 373 | printk("Device is bolixed, trying bus reset...\n"); |
| 374 | esp_bootup_reset(current_esp,current_esp->eregs); |
| 375 | } |
| 376 | } |
| 377 | } |
| 378 | |
| 379 | ESPDATA(("Transfer_finale: do_data_finale should come\n")); |
| 380 | |
| 381 | len = 0; |
| 382 | dma_on = 0; |
| 383 | dma_ints_on(current_esp); |
| 384 | } |
| 385 | |
| 386 | #endif |
| 387 | |
| 388 | /************************************************************* DMA Functions */ |
| 389 | static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count) |
| 390 | { |
| 391 | /* Since the CyberStorm DMA is fully dedicated to the ESP chip, |
| 392 | * the number of bytes sent (to the ESP chip) equals the number |
| 393 | * of bytes in the FIFO - there is no buffering in the DMA controller. |
| 394 | * XXXX Do I read this right? It is from host to ESP, right? |
| 395 | */ |
| 396 | return fifo_count; |
| 397 | } |
| 398 | |
| 399 | static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp) |
| 400 | { |
| 401 | unsigned long sz = sp->SCp.this_residual; |
| 402 | if(sz > DMA_MAXTRANSFER) |
| 403 | sz = DMA_MAXTRANSFER; |
| 404 | return sz; |
| 405 | } |
| 406 | |
| 407 | static void dma_dump_state(struct NCR_ESP *esp) |
| 408 | { |
| 409 | } |
| 410 | |
| 411 | /* |
| 412 | * What the f$@& is this? |
| 413 | * |
| 414 | * Some SCSI devices (like my Microtek ScanMaker 630 scanner) want to transfer |
| 415 | * more data than requested. How much? Dunno. So ditch the bogus data into |
| 416 | * the sink, hoping the device will advance to the next phase sooner or later. |
| 417 | * |
| 418 | * -- Carsten |
| 419 | */ |
| 420 | |
| 421 | static long oktag_eva_buffer[16]; /* The data sink */ |
| 422 | |
| 423 | static void oktag_check_dma(void) |
| 424 | { |
| 425 | struct NCR_ESP *esp; |
| 426 | |
| 427 | esp=current_esp; |
| 428 | if(!len) |
| 429 | { |
| 430 | address = oktag_eva_buffer; |
| 431 | len = 2; |
| 432 | /* esp_do_data sets them to zero like len */ |
| 433 | esp_write(current_esp->eregs->esp_tclow,2); |
| 434 | esp_write(current_esp->eregs->esp_tcmed,0); |
| 435 | } |
| 436 | } |
| 437 | |
| 438 | static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) |
| 439 | { |
| 440 | /* Zorro is noncached, everything else done using processor. */ |
| 441 | /* cache_clear(addr, length); */ |
| 442 | |
| 443 | if(dma_on) |
| 444 | panic("dma_init_read while dma process is initialized/running!\n"); |
| 445 | direction = 0; |
| 446 | address = (long *) vaddress; |
| 447 | current_esp = esp; |
| 448 | len = length; |
| 449 | oktag_check_dma(); |
| 450 | dma_on = 1; |
| 451 | } |
| 452 | |
| 453 | static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) |
| 454 | { |
| 455 | /* cache_push(addr, length); */ |
| 456 | |
| 457 | if(dma_on) |
| 458 | panic("dma_init_write while dma process is initialized/running!\n"); |
| 459 | direction = 1; |
| 460 | address = (long *) vaddress; |
| 461 | current_esp = esp; |
| 462 | len = length; |
| 463 | oktag_check_dma(); |
| 464 | dma_on = 1; |
| 465 | } |
| 466 | |
| 467 | static void dma_ints_off(struct NCR_ESP *esp) |
| 468 | { |
| 469 | disable_irq(esp->irq); |
| 470 | } |
| 471 | |
| 472 | static void dma_ints_on(struct NCR_ESP *esp) |
| 473 | { |
| 474 | enable_irq(esp->irq); |
| 475 | } |
| 476 | |
| 477 | static int dma_irq_p(struct NCR_ESP *esp) |
| 478 | { |
| 479 | /* It's important to check the DMA IRQ bit in the correct way! */ |
| 480 | return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR); |
| 481 | } |
| 482 | |
| 483 | static void dma_led_off(struct NCR_ESP *esp) |
| 484 | { |
| 485 | } |
| 486 | |
| 487 | static void dma_led_on(struct NCR_ESP *esp) |
| 488 | { |
| 489 | } |
| 490 | |
| 491 | static int dma_ports_p(struct NCR_ESP *esp) |
| 492 | { |
| 493 | return ((custom.intenar) & IF_PORTS); |
| 494 | } |
| 495 | |
| 496 | static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) |
| 497 | { |
| 498 | /* On the Sparc, DMA_ST_WRITE means "move data from device to memory" |
| 499 | * so when (write) is true, it actually means READ! |
| 500 | */ |
| 501 | if(write){ |
| 502 | dma_init_read(esp, addr, count); |
| 503 | } else { |
| 504 | dma_init_write(esp, addr, count); |
| 505 | } |
| 506 | } |
| 507 | |
| 508 | /* |
| 509 | * IRQ entry when DMA transfer is ready to be started |
| 510 | */ |
| 511 | |
| 512 | static void dma_irq_exit(struct NCR_ESP *esp) |
| 513 | { |
| 514 | #ifdef USE_BOTTOM_HALF |
| 515 | if(dma_on) |
| 516 | { |
| 517 | schedule_work(&tq_fake_dma); |
| 518 | } |
| 519 | #else |
| 520 | while(len && !dma_irq_p(esp)) |
| 521 | { |
| 522 | if(direction) |
| 523 | *paddress = *address++; |
| 524 | else |
| 525 | *address++ = *paddress; |
| 526 | len -= (sizeof(long)); |
| 527 | } |
| 528 | len = 0; |
| 529 | dma_on = 0; |
| 530 | #endif |
| 531 | } |
| 532 | |
| 533 | /* |
| 534 | * IRQ entry when DMA has just finished |
| 535 | */ |
| 536 | |
| 537 | static void dma_invalidate(struct NCR_ESP *esp) |
| 538 | { |
| 539 | } |
| 540 | |
| 541 | /* |
| 542 | * Since the processor does the data transfer we have to use the custom |
| 543 | * mmu interface to pass the virtual address, not the physical. |
| 544 | */ |
| 545 | |
| 546 | void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp) |
| 547 | { |
| 548 | sp->SCp.ptr = |
| 549 | sp->request_buffer; |
| 550 | } |
| 551 | |
| 552 | void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp) |
| 553 | { |
| 554 | sp->SCp.ptr = page_address(sp->SCp.buffer->page)+ |
| 555 | sp->SCp.buffer->offset; |
| 556 | } |
| 557 | |
| 558 | void dma_mmu_release_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp) |
| 559 | { |
| 560 | } |
| 561 | |
| 562 | void dma_mmu_release_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp) |
| 563 | { |
| 564 | } |
| 565 | |
| 566 | void dma_advance_sg(Scsi_Cmnd *sp) |
| 567 | { |
| 568 | sp->SCp.ptr = page_address(sp->SCp.buffer->page)+ |
| 569 | sp->SCp.buffer->offset; |
| 570 | } |
| 571 | |
| 572 | |
| 573 | #define HOSTS_C |
| 574 | |
| 575 | int oktagon_esp_release(struct Scsi_Host *instance) |
| 576 | { |
| 577 | #ifdef MODULE |
| 578 | unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev; |
| 579 | esp_release(); |
| 580 | release_mem_region(address, sizeof(struct ESP_regs)); |
| 581 | free_irq(IRQ_AMIGA_PORTS, esp_intr); |
| 582 | unregister_reboot_notifier(&oktagon_notifier); |
| 583 | #endif |
| 584 | return 1; |
| 585 | } |
| 586 | |
| 587 | |
Christoph Hellwig | d0be4a7d | 2005-10-31 18:31:40 +0100 | [diff] [blame] | 588 | static struct scsi_host_template driver_template = { |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 589 | .proc_name = "esp-oktagon", |
| 590 | .proc_info = &esp_proc_info, |
| 591 | .name = "BSC Oktagon SCSI", |
| 592 | .detect = oktagon_esp_detect, |
| 593 | .slave_alloc = esp_slave_alloc, |
| 594 | .slave_destroy = esp_slave_destroy, |
| 595 | .release = oktagon_esp_release, |
| 596 | .queuecommand = esp_queue, |
| 597 | .eh_abort_handler = esp_abort, |
| 598 | .eh_bus_reset_handler = esp_reset, |
| 599 | .can_queue = 7, |
| 600 | .this_id = 7, |
| 601 | .sg_tablesize = SG_ALL, |
| 602 | .cmd_per_lun = 1, |
| 603 | .use_clustering = ENABLE_CLUSTERING |
| 604 | }; |
| 605 | |
| 606 | |
| 607 | #include "scsi_module.c" |
| 608 | |
| 609 | MODULE_LICENSE("GPL"); |