g_NCR5380.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  1. /*
  2. * Generic Generic NCR5380 driver
  3. *
  4. * Copyright 1993, Drew Eckhardt
  5. * Visionary Computing
  6. * (Unix and Linux consulting and custom programming)
  7. * drew@colorado.edu
  8. * +1 (303) 440-4894
  9. *
  10. * NCR53C400 extensions (c) 1994,1995,1996, Kevin Lentin
  11. * K.Lentin@cs.monash.edu.au
  12. *
  13. * NCR53C400A extensions (c) 1996, Ingmar Baumgart
  14. * ingmar@gonzo.schwaben.de
  15. *
  16. * DTC3181E extensions (c) 1997, Ronald van Cuijlenborg
  17. * ronald.van.cuijlenborg@tip.nl or nutty@dds.nl
  18. *
  19. * Added ISAPNP support for DTC436 adapters,
  20. * Thomas Sailer, sailer@ife.ee.ethz.ch
  21. */
  22. /*
  23. * TODO : flesh out DMA support, find some one actually using this (I have
  24. * a memory mapped Trantor board that works fine)
  25. */
  26. /*
  27. * The card is detected and initialized in one of several ways :
  28. * 1. With command line overrides - NCR5380=port,irq may be
  29. * used on the LILO command line to override the defaults.
  30. *
  31. * 2. With the GENERIC_NCR5380_OVERRIDE compile time define. This is
  32. * specified as an array of address, irq, dma, board tuples. Ie, for
  33. * one board at 0x350, IRQ5, no dma, I could say
  34. * -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE, BOARD_NCR5380}}
  35. *
  36. * -1 should be specified for no or DMA interrupt, -2 to autoprobe for an
  37. * IRQ line if overridden on the command line.
  38. *
  39. * 3. When included as a module, with arguments passed on the command line:
  40. * ncr_irq=xx the interrupt
  41. * ncr_addr=xx the port or base address (for port or memory
  42. * mapped, resp.)
  43. * ncr_dma=xx the DMA
  44. * ncr_5380=1 to set up for a NCR5380 board
  45. * ncr_53c400=1 to set up for a NCR53C400 board
  46. * e.g.
  47. * modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
  48. * for a port mapped NCR5380 board or
  49. * modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
  50. * for a memory mapped NCR53C400 board with interrupts disabled.
  51. *
  52. * 255 should be specified for no or DMA interrupt, 254 to autoprobe for an
  53. * IRQ line if overridden on the command line.
  54. *
  55. */
  56. /* settings for DTC3181E card with only Mustek scanner attached */
  57. #define USLEEP_POLL msecs_to_jiffies(10)
  58. #define USLEEP_SLEEP msecs_to_jiffies(200)
  59. #define USLEEP_WAITLONG msecs_to_jiffies(5000)
  60. #define AUTOPROBE_IRQ
  61. #ifdef CONFIG_SCSI_GENERIC_NCR53C400
  62. #define NCR53C400_PSEUDO_DMA 1
  63. #define PSEUDO_DMA
  64. #define NCR53C400
  65. #endif
  66. #include <asm/io.h>
  67. #include <linux/signal.h>
  68. #include <linux/blkdev.h>
  69. #include <scsi/scsi_host.h>
  70. #include "g_NCR5380.h"
  71. #include "NCR5380.h"
  72. #include <linux/stat.h>
  73. #include <linux/init.h>
  74. #include <linux/ioport.h>
  75. #include <linux/isapnp.h>
  76. #include <linux/delay.h>
  77. #include <linux/interrupt.h>
  78. #define NCR_NOT_SET 0
  79. static int ncr_irq = NCR_NOT_SET;
  80. static int ncr_dma = NCR_NOT_SET;
  81. static int ncr_addr = NCR_NOT_SET;
  82. static int ncr_5380 = NCR_NOT_SET;
  83. static int ncr_53c400 = NCR_NOT_SET;
  84. static int ncr_53c400a = NCR_NOT_SET;
  85. static int dtc_3181e = NCR_NOT_SET;
  86. static struct override {
  87. NCR5380_map_type NCR5380_map_name;
  88. int irq;
  89. int dma;
  90. int board; /* Use NCR53c400, Ricoh, etc. extensions ? */
  91. } overrides
  92. #ifdef GENERIC_NCR5380_OVERRIDE
  93. [] __initdata = GENERIC_NCR5380_OVERRIDE;
  94. #else
  95. [1] __initdata = { { 0,},};
  96. #endif
  97. #define NO_OVERRIDES ARRAY_SIZE(overrides)
  98. #ifndef MODULE
  99. /**
  100. * internal_setup - handle lilo command string override
  101. * @board: BOARD_* identifier for the board
  102. * @str: unused
  103. * @ints: numeric parameters
  104. *
  105. * Do LILO command line initialization of the overrides array. Display
  106. * errors when needed
  107. *
  108. * Locks: none
  109. */
  110. static void __init internal_setup(int board, char *str, int *ints)
  111. {
  112. static int commandline_current = 0;
  113. switch (board) {
  114. case BOARD_NCR5380:
  115. if (ints[0] != 2 && ints[0] != 3) {
  116. printk(KERN_ERR "generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
  117. return;
  118. }
  119. break;
  120. case BOARD_NCR53C400:
  121. if (ints[0] != 2) {
  122. printk(KERN_ERR "generic_NCR53C400_setup : usage ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n");
  123. return;
  124. }
  125. break;
  126. case BOARD_NCR53C400A:
  127. if (ints[0] != 2) {
  128. printk(KERN_ERR "generic_NCR53C400A_setup : usage ncr53c400a=" STRVAL(NCR5380_map_name) ",irq\n");
  129. return;
  130. }
  131. break;
  132. case BOARD_DTC3181E:
  133. if (ints[0] != 2) {
  134. printk("generic_DTC3181E_setup : usage dtc3181e=" STRVAL(NCR5380_map_name) ",irq\n");
  135. return;
  136. }
  137. break;
  138. }
  139. if (commandline_current < NO_OVERRIDES) {
  140. overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type) ints[1];
  141. overrides[commandline_current].irq = ints[2];
  142. if (ints[0] == 3)
  143. overrides[commandline_current].dma = ints[3];
  144. else
  145. overrides[commandline_current].dma = DMA_NONE;
  146. overrides[commandline_current].board = board;
  147. ++commandline_current;
  148. }
  149. }
  150. /**
  151. * do_NCR53C80_setup - set up entry point
  152. * @str: unused
  153. *
  154. * Setup function invoked at boot to parse the ncr5380= command
  155. * line.
  156. */
  157. static int __init do_NCR5380_setup(char *str)
  158. {
  159. int ints[10];
  160. get_options(str, ARRAY_SIZE(ints), ints);
  161. internal_setup(BOARD_NCR5380, str, ints);
  162. return 1;
  163. }
  164. /**
  165. * do_NCR53C400_setup - set up entry point
  166. * @str: unused
  167. * @ints: integer parameters from kernel setup code
  168. *
  169. * Setup function invoked at boot to parse the ncr53c400= command
  170. * line.
  171. */
  172. static int __init do_NCR53C400_setup(char *str)
  173. {
  174. int ints[10];
  175. get_options(str, ARRAY_SIZE(ints), ints);
  176. internal_setup(BOARD_NCR53C400, str, ints);
  177. return 1;
  178. }
  179. /**
  180. * do_NCR53C400A_setup - set up entry point
  181. * @str: unused
  182. * @ints: integer parameters from kernel setup code
  183. *
  184. * Setup function invoked at boot to parse the ncr53c400a= command
  185. * line.
  186. */
  187. static int __init do_NCR53C400A_setup(char *str)
  188. {
  189. int ints[10];
  190. get_options(str, ARRAY_SIZE(ints), ints);
  191. internal_setup(BOARD_NCR53C400A, str, ints);
  192. return 1;
  193. }
  194. /**
  195. * do_DTC3181E_setup - set up entry point
  196. * @str: unused
  197. * @ints: integer parameters from kernel setup code
  198. *
  199. * Setup function invoked at boot to parse the dtc3181e= command
  200. * line.
  201. */
  202. static int __init do_DTC3181E_setup(char *str)
  203. {
  204. int ints[10];
  205. get_options(str, ARRAY_SIZE(ints), ints);
  206. internal_setup(BOARD_DTC3181E, str, ints);
  207. return 1;
  208. }
  209. #endif
  210. /**
  211. * generic_NCR5380_detect - look for NCR5380 controllers
  212. * @tpnt: the scsi template
  213. *
  214. * Scan for the present of NCR5380, NCR53C400, NCR53C400A, DTC3181E
  215. * and DTC436(ISAPnP) controllers. If overrides have been set we use
  216. * them.
  217. *
  218. * The caller supplied NCR5380_init function is invoked from here, before
  219. * the interrupt line is taken.
  220. *
  221. * Locks: none
  222. */
  223. static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
  224. {
  225. static int current_override = 0;
  226. int count;
  227. unsigned int *ports;
  228. #ifndef SCSI_G_NCR5380_MEM
  229. int i;
  230. unsigned long region_size = 16;
  231. #endif
  232. static unsigned int __initdata ncr_53c400a_ports[] = {
  233. 0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
  234. };
  235. static unsigned int __initdata dtc_3181e_ports[] = {
  236. 0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
  237. };
  238. int flags = 0;
  239. struct Scsi_Host *instance;
  240. #ifdef SCSI_G_NCR5380_MEM
  241. unsigned long base;
  242. void __iomem *iomem;
  243. #endif
  244. if (ncr_irq != NCR_NOT_SET)
  245. overrides[0].irq = ncr_irq;
  246. if (ncr_dma != NCR_NOT_SET)
  247. overrides[0].dma = ncr_dma;
  248. if (ncr_addr != NCR_NOT_SET)
  249. overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr;
  250. if (ncr_5380 != NCR_NOT_SET)
  251. overrides[0].board = BOARD_NCR5380;
  252. else if (ncr_53c400 != NCR_NOT_SET)
  253. overrides[0].board = BOARD_NCR53C400;
  254. else if (ncr_53c400a != NCR_NOT_SET)
  255. overrides[0].board = BOARD_NCR53C400A;
  256. else if (dtc_3181e != NCR_NOT_SET)
  257. overrides[0].board = BOARD_DTC3181E;
  258. #ifndef SCSI_G_NCR5380_MEM
  259. if (!current_override && isapnp_present()) {
  260. struct pnp_dev *dev = NULL;
  261. count = 0;
  262. while ((dev = pnp_find_dev(NULL, ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e), dev))) {
  263. if (count >= NO_OVERRIDES)
  264. break;
  265. if (pnp_device_attach(dev) < 0)
  266. continue;
  267. if (pnp_activate_dev(dev) < 0) {
  268. printk(KERN_ERR "dtc436e probe: activate failed\n");
  269. pnp_device_detach(dev);
  270. continue;
  271. }
  272. if (!pnp_port_valid(dev, 0)) {
  273. printk(KERN_ERR "dtc436e probe: no valid port\n");
  274. pnp_device_detach(dev);
  275. continue;
  276. }
  277. if (pnp_irq_valid(dev, 0))
  278. overrides[count].irq = pnp_irq(dev, 0);
  279. else
  280. overrides[count].irq = NO_IRQ;
  281. if (pnp_dma_valid(dev, 0))
  282. overrides[count].dma = pnp_dma(dev, 0);
  283. else
  284. overrides[count].dma = DMA_NONE;
  285. overrides[count].NCR5380_map_name = (NCR5380_map_type) pnp_port_start(dev, 0);
  286. overrides[count].board = BOARD_DTC3181E;
  287. count++;
  288. }
  289. }
  290. #endif
  291. tpnt->proc_name = "g_NCR5380";
  292. for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
  293. if (!(overrides[current_override].NCR5380_map_name))
  294. continue;
  295. ports = NULL;
  296. switch (overrides[current_override].board) {
  297. case BOARD_NCR5380:
  298. flags = FLAG_NO_PSEUDO_DMA;
  299. break;
  300. case BOARD_NCR53C400:
  301. flags = FLAG_NCR53C400;
  302. break;
  303. case BOARD_NCR53C400A:
  304. flags = FLAG_NO_PSEUDO_DMA;
  305. ports = ncr_53c400a_ports;
  306. break;
  307. case BOARD_DTC3181E:
  308. flags = FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E;
  309. ports = dtc_3181e_ports;
  310. break;
  311. }
  312. #ifndef SCSI_G_NCR5380_MEM
  313. if (ports) {
  314. /* wakeup sequence for the NCR53C400A and DTC3181E */
  315. /* Disable the adapter and look for a free io port */
  316. outb(0x59, 0x779);
  317. outb(0xb9, 0x379);
  318. outb(0xc5, 0x379);
  319. outb(0xae, 0x379);
  320. outb(0xa6, 0x379);
  321. outb(0x00, 0x379);
  322. if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
  323. for (i = 0; ports[i]; i++) {
  324. if (!request_region(ports[i], 16, "ncr53c80"))
  325. continue;
  326. if (overrides[current_override].NCR5380_map_name == ports[i])
  327. break;
  328. release_region(ports[i], 16);
  329. } else
  330. for (i = 0; ports[i]; i++) {
  331. if (!request_region(ports[i], 16, "ncr53c80"))
  332. continue;
  333. if (inb(ports[i]) == 0xff)
  334. break;
  335. release_region(ports[i], 16);
  336. }
  337. if (ports[i]) {
  338. /* At this point we have our region reserved */
  339. outb(0x59, 0x779);
  340. outb(0xb9, 0x379);
  341. outb(0xc5, 0x379);
  342. outb(0xae, 0x379);
  343. outb(0xa6, 0x379);
  344. outb(0x80 | i, 0x379); /* set io port to be used */
  345. outb(0xc0, ports[i] + 9);
  346. if (inb(ports[i] + 9) != 0x80)
  347. continue;
  348. else
  349. overrides[current_override].NCR5380_map_name = ports[i];
  350. } else
  351. continue;
  352. }
  353. else
  354. {
  355. /* Not a 53C400A style setup - just grab */
  356. if(!(request_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size, "ncr5380")))
  357. continue;
  358. region_size = NCR5380_region_size;
  359. }
  360. #else
  361. base = overrides[current_override].NCR5380_map_name;
  362. if (!request_mem_region(base, NCR5380_region_size, "ncr5380"))
  363. continue;
  364. iomem = ioremap(base, NCR5380_region_size);
  365. if (!iomem) {
  366. release_mem_region(base, NCR5380_region_size);
  367. continue;
  368. }
  369. #endif
  370. instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
  371. if (instance == NULL) {
  372. #ifndef SCSI_G_NCR5380_MEM
  373. release_region(overrides[current_override].NCR5380_map_name, region_size);
  374. #else
  375. iounmap(iomem);
  376. release_mem_region(base, NCR5380_region_size);
  377. #endif
  378. continue;
  379. }
  380. instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
  381. #ifndef SCSI_G_NCR5380_MEM
  382. instance->n_io_port = region_size;
  383. #else
  384. ((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
  385. #endif
  386. NCR5380_init(instance, flags);
  387. if (overrides[current_override].irq != IRQ_AUTO)
  388. instance->irq = overrides[current_override].irq;
  389. else
  390. instance->irq = NCR5380_probe_irq(instance, 0xffff);
  391. /* Compatibility with documented NCR5380 kernel parameters */
  392. if (instance->irq == 255)
  393. instance->irq = NO_IRQ;
  394. if (instance->irq != NO_IRQ)
  395. if (request_irq(instance->irq, generic_NCR5380_intr,
  396. 0, "NCR5380", instance)) {
  397. printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
  398. instance->irq = NO_IRQ;
  399. }
  400. if (instance->irq == NO_IRQ) {
  401. printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
  402. printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
  403. }
  404. ++current_override;
  405. ++count;
  406. }
  407. return count;
  408. }
  409. /**
  410. * generic_NCR5380_release_resources - free resources
  411. * @instance: host adapter to clean up
  412. *
  413. * Free the generic interface resources from this adapter.
  414. *
  415. * Locks: none
  416. */
  417. static int generic_NCR5380_release_resources(struct Scsi_Host *instance)
  418. {
  419. NCR5380_local_declare();
  420. NCR5380_setup(instance);
  421. if (instance->irq != NO_IRQ)
  422. free_irq(instance->irq, instance);
  423. NCR5380_exit(instance);
  424. #ifndef SCSI_G_NCR5380_MEM
  425. release_region(instance->NCR5380_instance_name, instance->n_io_port);
  426. #else
  427. iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem);
  428. release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size);
  429. #endif
  430. return 0;
  431. }
  432. #ifdef BIOSPARAM
  433. /**
  434. * generic_NCR5380_biosparam
  435. * @disk: disk to compute geometry for
  436. * @dev: device identifier for this disk
  437. * @ip: sizes to fill in
  438. *
  439. * Generates a BIOS / DOS compatible H-C-S mapping for the specified
  440. * device / size.
  441. *
  442. * XXX Most SCSI boards use this mapping, I could be incorrect. Someone
  443. * using hard disks on a trantor should verify that this mapping
  444. * corresponds to that used by the BIOS / ASPI driver by running the linux
  445. * fdisk program and matching the H_C_S coordinates to what DOS uses.
  446. *
  447. * Locks: none
  448. */
  449. static int
  450. generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
  451. sector_t capacity, int *ip)
  452. {
  453. ip[0] = 64;
  454. ip[1] = 32;
  455. ip[2] = capacity >> 11;
  456. return 0;
  457. }
  458. #endif
  459. #ifdef NCR53C400_PSEUDO_DMA
  460. /**
  461. * NCR5380_pread - pseudo DMA read
  462. * @instance: adapter to read from
  463. * @dst: buffer to read into
  464. * @len: buffer length
  465. *
  466. * Perform a pseudo DMA mode read from an NCR53C400 or equivalent
  467. * controller
  468. */
  469. static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
  470. {
  471. int blocks = len / 128;
  472. int start = 0;
  473. int bl;
  474. NCR5380_local_declare();
  475. NCR5380_setup(instance);
  476. NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
  477. NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
  478. while (1) {
  479. if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
  480. break;
  481. }
  482. if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
  483. printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
  484. return -1;
  485. }
  486. while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
  487. {
  488. // FIXME - no timeout
  489. }
  490. #ifndef SCSI_G_NCR5380_MEM
  491. {
  492. int i;
  493. for (i = 0; i < 128; i++)
  494. dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
  495. }
  496. #else
  497. /* implies SCSI_G_NCR5380_MEM */
  498. memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128);
  499. #endif
  500. start += 128;
  501. blocks--;
  502. }
  503. if (blocks) {
  504. while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
  505. {
  506. // FIXME - no timeout
  507. }
  508. #ifndef SCSI_G_NCR5380_MEM
  509. {
  510. int i;
  511. for (i = 0; i < 128; i++)
  512. dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
  513. }
  514. #else
  515. /* implies SCSI_G_NCR5380_MEM */
  516. memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128);
  517. #endif
  518. start += 128;
  519. blocks--;
  520. }
  521. if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
  522. printk("53C400r: no 53C80 gated irq after transfer");
  523. #if 0
  524. /*
  525. * DON'T DO THIS - THEY NEVER ARRIVE!
  526. */
  527. printk("53C400r: Waiting for 53C80 registers\n");
  528. while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
  529. ;
  530. #endif
  531. if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
  532. printk(KERN_ERR "53C400r: no end dma signal\n");
  533. NCR5380_write(MODE_REG, MR_BASE);
  534. NCR5380_read(RESET_PARITY_INTERRUPT_REG);
  535. return 0;
  536. }
  537. /**
  538. * NCR5380_write - pseudo DMA write
  539. * @instance: adapter to read from
  540. * @dst: buffer to read into
  541. * @len: buffer length
  542. *
  543. * Perform a pseudo DMA mode read from an NCR53C400 or equivalent
  544. * controller
  545. */
  546. static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
  547. {
  548. int blocks = len / 128;
  549. int start = 0;
  550. int bl;
  551. int i;
  552. NCR5380_local_declare();
  553. NCR5380_setup(instance);
  554. NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
  555. NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
  556. while (1) {
  557. if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
  558. printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
  559. return -1;
  560. }
  561. if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
  562. break;
  563. }
  564. while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
  565. ; // FIXME - timeout
  566. #ifndef SCSI_G_NCR5380_MEM
  567. {
  568. for (i = 0; i < 128; i++)
  569. NCR5380_write(C400_HOST_BUFFER, src[start + i]);
  570. }
  571. #else
  572. /* implies SCSI_G_NCR5380_MEM */
  573. memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128);
  574. #endif
  575. start += 128;
  576. blocks--;
  577. }
  578. if (blocks) {
  579. while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
  580. ; // FIXME - no timeout
  581. #ifndef SCSI_G_NCR5380_MEM
  582. {
  583. for (i = 0; i < 128; i++)
  584. NCR5380_write(C400_HOST_BUFFER, src[start + i]);
  585. }
  586. #else
  587. /* implies SCSI_G_NCR5380_MEM */
  588. memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128);
  589. #endif
  590. start += 128;
  591. blocks--;
  592. }
  593. #if 0
  594. printk("53C400w: waiting for registers to be available\n");
  595. THEY NEVER DO ! while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG);
  596. printk("53C400w: Got em\n");
  597. #endif
  598. /* Let's wait for this instead - could be ugly */
  599. /* All documentation says to check for this. Maybe my hardware is too
  600. * fast. Waiting for it seems to work fine! KLL
  601. */
  602. while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
  603. ; // FIXME - no timeout
  604. /*
  605. * I know. i is certainly != 0 here but the loop is new. See previous
  606. * comment.
  607. */
  608. if (i) {
  609. if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
  610. printk(KERN_ERR "53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i);
  611. } else
  612. printk(KERN_ERR "53C400w: no 53C80 gated irq after transfer (last block)\n");
  613. #if 0
  614. if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
  615. printk(KERN_ERR "53C400w: no end dma signal\n");
  616. }
  617. #endif
  618. while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
  619. ; // TIMEOUT
  620. return 0;
  621. }
  622. #endif /* PSEUDO_DMA */
  623. /*
  624. * Include the NCR5380 core code that we build our driver around
  625. */
  626. #include "NCR5380.c"
  627. static struct scsi_host_template driver_template = {
  628. .show_info = generic_NCR5380_show_info,
  629. .name = "Generic NCR5380/NCR53C400 SCSI",
  630. .detect = generic_NCR5380_detect,
  631. .release = generic_NCR5380_release_resources,
  632. .info = generic_NCR5380_info,
  633. .queuecommand = generic_NCR5380_queue_command,
  634. .eh_abort_handler = generic_NCR5380_abort,
  635. .eh_bus_reset_handler = generic_NCR5380_bus_reset,
  636. .bios_param = NCR5380_BIOSPARAM,
  637. .can_queue = CAN_QUEUE,
  638. .this_id = 7,
  639. .sg_tablesize = SG_ALL,
  640. .cmd_per_lun = CMD_PER_LUN,
  641. .use_clustering = DISABLE_CLUSTERING,
  642. };
  643. #include <linux/module.h>
  644. #include "scsi_module.c"
  645. module_param(ncr_irq, int, 0);
  646. module_param(ncr_dma, int, 0);
  647. module_param(ncr_addr, int, 0);
  648. module_param(ncr_5380, int, 0);
  649. module_param(ncr_53c400, int, 0);
  650. module_param(ncr_53c400a, int, 0);
  651. module_param(dtc_3181e, int, 0);
  652. MODULE_LICENSE("GPL");
  653. #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE)
  654. static struct isapnp_device_id id_table[] = {
  655. {
  656. ISAPNP_ANY_ID, ISAPNP_ANY_ID,
  657. ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e),
  658. 0},
  659. {0}
  660. };
  661. MODULE_DEVICE_TABLE(isapnp, id_table);
  662. #endif
  663. __setup("ncr5380=", do_NCR5380_setup);
  664. __setup("ncr53c400=", do_NCR53C400_setup);
  665. __setup("ncr53c400a=", do_NCR53C400A_setup);
  666. __setup("dtc3181e=", do_DTC3181E_setup);