g_NCR5380.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  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. * See Documentation/scsi/g_NCR5380.txt for more info.
  23. */
  24. #include <asm/io.h>
  25. #include <linux/blkdev.h>
  26. #include <linux/module.h>
  27. #include <scsi/scsi_host.h>
  28. #include <linux/init.h>
  29. #include <linux/ioport.h>
  30. #include <linux/isa.h>
  31. #include <linux/pnp.h>
  32. #include <linux/interrupt.h>
  33. /* Definitions for the core NCR5380 driver. */
  34. #define NCR5380_read(reg) \
  35. ioread8(hostdata->io + hostdata->offset + (reg))
  36. #define NCR5380_write(reg, value) \
  37. iowrite8(value, hostdata->io + hostdata->offset + (reg))
  38. #define NCR5380_implementation_fields \
  39. int offset; \
  40. int c400_ctl_status; \
  41. int c400_blk_cnt; \
  42. int c400_host_buf; \
  43. int io_width; \
  44. int pdma_residual; \
  45. int board
  46. #define NCR5380_dma_xfer_len generic_NCR5380_dma_xfer_len
  47. #define NCR5380_dma_recv_setup generic_NCR5380_precv
  48. #define NCR5380_dma_send_setup generic_NCR5380_psend
  49. #define NCR5380_dma_residual generic_NCR5380_dma_residual
  50. #define NCR5380_intr generic_NCR5380_intr
  51. #define NCR5380_queue_command generic_NCR5380_queue_command
  52. #define NCR5380_abort generic_NCR5380_abort
  53. #define NCR5380_host_reset generic_NCR5380_host_reset
  54. #define NCR5380_info generic_NCR5380_info
  55. #define NCR5380_io_delay(x) udelay(x)
  56. #include "NCR5380.h"
  57. #define DRV_MODULE_NAME "g_NCR5380"
  58. #define NCR53C400_mem_base 0x3880
  59. #define NCR53C400_host_buffer 0x3900
  60. #define NCR53C400_region_size 0x3a00
  61. #define BOARD_NCR5380 0
  62. #define BOARD_NCR53C400 1
  63. #define BOARD_NCR53C400A 2
  64. #define BOARD_DTC3181E 3
  65. #define BOARD_HP_C2502 4
  66. #define IRQ_AUTO 254
  67. #define MAX_CARDS 8
  68. #define DMA_MAX_SIZE 32768
  69. /* old-style parameters for compatibility */
  70. static int ncr_irq = -1;
  71. static int ncr_addr;
  72. static int ncr_5380;
  73. static int ncr_53c400;
  74. static int ncr_53c400a;
  75. static int dtc_3181e;
  76. static int hp_c2502;
  77. module_param_hw(ncr_irq, int, irq, 0);
  78. module_param_hw(ncr_addr, int, ioport, 0);
  79. module_param(ncr_5380, int, 0);
  80. module_param(ncr_53c400, int, 0);
  81. module_param(ncr_53c400a, int, 0);
  82. module_param(dtc_3181e, int, 0);
  83. module_param(hp_c2502, int, 0);
  84. static int irq[] = { -1, -1, -1, -1, -1, -1, -1, -1 };
  85. module_param_hw_array(irq, int, irq, NULL, 0);
  86. MODULE_PARM_DESC(irq, "IRQ number(s) (0=none, 254=auto [default])");
  87. static int base[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  88. module_param_hw_array(base, int, ioport, NULL, 0);
  89. MODULE_PARM_DESC(base, "base address(es)");
  90. static int card[] = { -1, -1, -1, -1, -1, -1, -1, -1 };
  91. module_param_array(card, int, NULL, 0);
  92. MODULE_PARM_DESC(card, "card type (0=NCR5380, 1=NCR53C400, 2=NCR53C400A, 3=DTC3181E, 4=HP C2502)");
  93. MODULE_ALIAS("g_NCR5380_mmio");
  94. MODULE_LICENSE("GPL");
  95. static void g_NCR5380_trigger_irq(struct Scsi_Host *instance)
  96. {
  97. struct NCR5380_hostdata *hostdata = shost_priv(instance);
  98. /*
  99. * An interrupt is triggered whenever BSY = false, SEL = true
  100. * and a bit set in the SELECT_ENABLE_REG is asserted on the
  101. * SCSI bus.
  102. *
  103. * Note that the bus is only driven when the phase control signals
  104. * (I/O, C/D, and MSG) match those in the TCR.
  105. */
  106. NCR5380_write(TARGET_COMMAND_REG,
  107. PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
  108. NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
  109. NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
  110. NCR5380_write(INITIATOR_COMMAND_REG,
  111. ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL);
  112. msleep(1);
  113. NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
  114. NCR5380_write(SELECT_ENABLE_REG, 0);
  115. NCR5380_write(TARGET_COMMAND_REG, 0);
  116. }
  117. /**
  118. * g_NCR5380_probe_irq - find the IRQ of a NCR5380 or equivalent
  119. * @instance: SCSI host instance
  120. *
  121. * Autoprobe for the IRQ line used by the card by triggering an IRQ
  122. * and then looking to see what interrupt actually turned up.
  123. */
  124. static int g_NCR5380_probe_irq(struct Scsi_Host *instance)
  125. {
  126. struct NCR5380_hostdata *hostdata = shost_priv(instance);
  127. int irq_mask, irq;
  128. NCR5380_read(RESET_PARITY_INTERRUPT_REG);
  129. irq_mask = probe_irq_on();
  130. g_NCR5380_trigger_irq(instance);
  131. irq = probe_irq_off(irq_mask);
  132. NCR5380_read(RESET_PARITY_INTERRUPT_REG);
  133. if (irq <= 0)
  134. return NO_IRQ;
  135. return irq;
  136. }
  137. /*
  138. * Configure I/O address of 53C400A or DTC436 by writing magic numbers
  139. * to ports 0x779 and 0x379.
  140. */
  141. static void magic_configure(int idx, u8 irq, u8 magic[])
  142. {
  143. u8 cfg = 0;
  144. outb(magic[0], 0x779);
  145. outb(magic[1], 0x379);
  146. outb(magic[2], 0x379);
  147. outb(magic[3], 0x379);
  148. outb(magic[4], 0x379);
  149. if (irq == 9)
  150. irq = 2;
  151. if (idx >= 0 && idx <= 7)
  152. cfg = 0x80 | idx | (irq << 4);
  153. outb(cfg, 0x379);
  154. }
  155. static irqreturn_t legacy_empty_irq_handler(int irq, void *dev_id)
  156. {
  157. return IRQ_HANDLED;
  158. }
  159. static int legacy_find_free_irq(int *irq_table)
  160. {
  161. while (*irq_table != -1) {
  162. if (!request_irq(*irq_table, legacy_empty_irq_handler,
  163. IRQF_PROBE_SHARED, "Test IRQ",
  164. (void *)irq_table)) {
  165. free_irq(*irq_table, (void *) irq_table);
  166. return *irq_table;
  167. }
  168. irq_table++;
  169. }
  170. return -1;
  171. }
  172. static unsigned int ncr_53c400a_ports[] = {
  173. 0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
  174. };
  175. static unsigned int dtc_3181e_ports[] = {
  176. 0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
  177. };
  178. static u8 ncr_53c400a_magic[] = { /* 53C400A & DTC436 */
  179. 0x59, 0xb9, 0xc5, 0xae, 0xa6
  180. };
  181. static u8 hp_c2502_magic[] = { /* HP C2502 */
  182. 0x0f, 0x22, 0xf0, 0x20, 0x80
  183. };
  184. static int hp_c2502_irqs[] = {
  185. 9, 5, 7, 3, 4, -1
  186. };
  187. static int generic_NCR5380_init_one(struct scsi_host_template *tpnt,
  188. struct device *pdev, int base, int irq, int board)
  189. {
  190. bool is_pmio = base <= 0xffff;
  191. int ret;
  192. int flags = 0;
  193. unsigned int *ports = NULL;
  194. u8 *magic = NULL;
  195. int i;
  196. int port_idx = -1;
  197. unsigned long region_size;
  198. struct Scsi_Host *instance;
  199. struct NCR5380_hostdata *hostdata;
  200. u8 __iomem *iomem;
  201. switch (board) {
  202. case BOARD_NCR5380:
  203. flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP;
  204. break;
  205. case BOARD_NCR53C400A:
  206. ports = ncr_53c400a_ports;
  207. magic = ncr_53c400a_magic;
  208. break;
  209. case BOARD_HP_C2502:
  210. ports = ncr_53c400a_ports;
  211. magic = hp_c2502_magic;
  212. break;
  213. case BOARD_DTC3181E:
  214. ports = dtc_3181e_ports;
  215. magic = ncr_53c400a_magic;
  216. break;
  217. }
  218. if (is_pmio && ports && magic) {
  219. /* wakeup sequence for the NCR53C400A and DTC3181E */
  220. /* Disable the adapter and look for a free io port */
  221. magic_configure(-1, 0, magic);
  222. region_size = 16;
  223. if (base)
  224. for (i = 0; ports[i]; i++) {
  225. if (base == ports[i]) { /* index found */
  226. if (!request_region(ports[i],
  227. region_size,
  228. "ncr53c80"))
  229. return -EBUSY;
  230. break;
  231. }
  232. }
  233. else
  234. for (i = 0; ports[i]; i++) {
  235. if (!request_region(ports[i], region_size,
  236. "ncr53c80"))
  237. continue;
  238. if (inb(ports[i]) == 0xff)
  239. break;
  240. release_region(ports[i], region_size);
  241. }
  242. if (ports[i]) {
  243. /* At this point we have our region reserved */
  244. magic_configure(i, 0, magic); /* no IRQ yet */
  245. base = ports[i];
  246. outb(0xc0, base + 9);
  247. if (inb(base + 9) != 0x80) {
  248. ret = -ENODEV;
  249. goto out_release;
  250. }
  251. port_idx = i;
  252. } else
  253. return -EINVAL;
  254. } else if (is_pmio) {
  255. /* NCR5380 - no configuration, just grab */
  256. region_size = 8;
  257. if (!base || !request_region(base, region_size, "ncr5380"))
  258. return -EBUSY;
  259. } else { /* MMIO */
  260. region_size = NCR53C400_region_size;
  261. if (!request_mem_region(base, region_size, "ncr5380"))
  262. return -EBUSY;
  263. }
  264. if (is_pmio)
  265. iomem = ioport_map(base, region_size);
  266. else
  267. iomem = ioremap(base, region_size);
  268. if (!iomem) {
  269. ret = -ENOMEM;
  270. goto out_release;
  271. }
  272. instance = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata));
  273. if (instance == NULL) {
  274. ret = -ENOMEM;
  275. goto out_unmap;
  276. }
  277. hostdata = shost_priv(instance);
  278. hostdata->board = board;
  279. hostdata->io = iomem;
  280. hostdata->region_size = region_size;
  281. if (is_pmio) {
  282. hostdata->io_port = base;
  283. hostdata->io_width = 1; /* 8-bit PDMA by default */
  284. hostdata->offset = 0;
  285. /*
  286. * On NCR53C400 boards, NCR5380 registers are mapped 8 past
  287. * the base address.
  288. */
  289. switch (board) {
  290. case BOARD_NCR53C400:
  291. hostdata->io_port += 8;
  292. hostdata->c400_ctl_status = 0;
  293. hostdata->c400_blk_cnt = 1;
  294. hostdata->c400_host_buf = 4;
  295. break;
  296. case BOARD_DTC3181E:
  297. hostdata->io_width = 2; /* 16-bit PDMA */
  298. /* fall through */
  299. case BOARD_NCR53C400A:
  300. case BOARD_HP_C2502:
  301. hostdata->c400_ctl_status = 9;
  302. hostdata->c400_blk_cnt = 10;
  303. hostdata->c400_host_buf = 8;
  304. break;
  305. }
  306. } else {
  307. hostdata->base = base;
  308. hostdata->offset = NCR53C400_mem_base;
  309. switch (board) {
  310. case BOARD_NCR53C400:
  311. hostdata->c400_ctl_status = 0x100;
  312. hostdata->c400_blk_cnt = 0x101;
  313. hostdata->c400_host_buf = 0x104;
  314. break;
  315. case BOARD_DTC3181E:
  316. case BOARD_NCR53C400A:
  317. case BOARD_HP_C2502:
  318. pr_err(DRV_MODULE_NAME ": unknown register offsets\n");
  319. ret = -EINVAL;
  320. goto out_unregister;
  321. }
  322. }
  323. /* Check for vacant slot */
  324. NCR5380_write(MODE_REG, 0);
  325. if (NCR5380_read(MODE_REG) != 0) {
  326. ret = -ENODEV;
  327. goto out_unregister;
  328. }
  329. ret = NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP);
  330. if (ret)
  331. goto out_unregister;
  332. switch (board) {
  333. case BOARD_NCR53C400:
  334. case BOARD_DTC3181E:
  335. case BOARD_NCR53C400A:
  336. case BOARD_HP_C2502:
  337. NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
  338. }
  339. NCR5380_maybe_reset_bus(instance);
  340. /* Compatibility with documented NCR5380 kernel parameters */
  341. if (irq == 255 || irq == 0)
  342. irq = NO_IRQ;
  343. else if (irq == -1)
  344. irq = IRQ_AUTO;
  345. if (board == BOARD_HP_C2502) {
  346. int *irq_table = hp_c2502_irqs;
  347. int board_irq = -1;
  348. switch (irq) {
  349. case NO_IRQ:
  350. board_irq = 0;
  351. break;
  352. case IRQ_AUTO:
  353. board_irq = legacy_find_free_irq(irq_table);
  354. break;
  355. default:
  356. while (*irq_table != -1)
  357. if (*irq_table++ == irq)
  358. board_irq = irq;
  359. }
  360. if (board_irq <= 0) {
  361. board_irq = 0;
  362. irq = NO_IRQ;
  363. }
  364. magic_configure(port_idx, board_irq, magic);
  365. }
  366. if (irq == IRQ_AUTO) {
  367. instance->irq = g_NCR5380_probe_irq(instance);
  368. if (instance->irq == NO_IRQ)
  369. shost_printk(KERN_INFO, instance, "no irq detected\n");
  370. } else {
  371. instance->irq = irq;
  372. if (instance->irq == NO_IRQ)
  373. shost_printk(KERN_INFO, instance, "no irq provided\n");
  374. }
  375. if (instance->irq != NO_IRQ) {
  376. if (request_irq(instance->irq, generic_NCR5380_intr,
  377. 0, "NCR5380", instance)) {
  378. instance->irq = NO_IRQ;
  379. shost_printk(KERN_INFO, instance,
  380. "irq %d denied\n", instance->irq);
  381. } else {
  382. shost_printk(KERN_INFO, instance,
  383. "irq %d acquired\n", instance->irq);
  384. }
  385. }
  386. ret = scsi_add_host(instance, pdev);
  387. if (ret)
  388. goto out_free_irq;
  389. scsi_scan_host(instance);
  390. dev_set_drvdata(pdev, instance);
  391. return 0;
  392. out_free_irq:
  393. if (instance->irq != NO_IRQ)
  394. free_irq(instance->irq, instance);
  395. NCR5380_exit(instance);
  396. out_unregister:
  397. scsi_host_put(instance);
  398. out_unmap:
  399. iounmap(iomem);
  400. out_release:
  401. if (is_pmio)
  402. release_region(base, region_size);
  403. else
  404. release_mem_region(base, region_size);
  405. return ret;
  406. }
  407. static void generic_NCR5380_release_resources(struct Scsi_Host *instance)
  408. {
  409. struct NCR5380_hostdata *hostdata = shost_priv(instance);
  410. void __iomem *iomem = hostdata->io;
  411. unsigned long io_port = hostdata->io_port;
  412. unsigned long base = hostdata->base;
  413. unsigned long region_size = hostdata->region_size;
  414. scsi_remove_host(instance);
  415. if (instance->irq != NO_IRQ)
  416. free_irq(instance->irq, instance);
  417. NCR5380_exit(instance);
  418. scsi_host_put(instance);
  419. iounmap(iomem);
  420. if (io_port)
  421. release_region(io_port, region_size);
  422. else
  423. release_mem_region(base, region_size);
  424. }
  425. /* wait_for_53c80_access - wait for 53C80 registers to become accessible
  426. * @hostdata: scsi host private data
  427. *
  428. * The registers within the 53C80 logic block are inaccessible until
  429. * bit 7 in the 53C400 control status register gets asserted.
  430. */
  431. static void wait_for_53c80_access(struct NCR5380_hostdata *hostdata)
  432. {
  433. int count = 10000;
  434. do {
  435. if (hostdata->board == BOARD_DTC3181E)
  436. udelay(4); /* DTC436 chip hangs without this */
  437. if (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
  438. return;
  439. } while (--count > 0);
  440. scmd_printk(KERN_ERR, hostdata->connected,
  441. "53c80 registers not accessible, device will be reset\n");
  442. NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
  443. NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
  444. }
  445. /**
  446. * generic_NCR5380_precv - pseudo DMA receive
  447. * @hostdata: scsi host private data
  448. * @dst: buffer to write into
  449. * @len: transfer size
  450. *
  451. * Perform a pseudo DMA mode receive from a 53C400 or equivalent device.
  452. */
  453. static inline int generic_NCR5380_precv(struct NCR5380_hostdata *hostdata,
  454. unsigned char *dst, int len)
  455. {
  456. int residual;
  457. int start = 0;
  458. NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
  459. NCR5380_write(hostdata->c400_blk_cnt, len / 128);
  460. do {
  461. if (start == len - 128) {
  462. /* Ignore End of DMA interrupt for the final buffer */
  463. if (NCR5380_poll_politely(hostdata, hostdata->c400_ctl_status,
  464. CSR_HOST_BUF_NOT_RDY, 0, HZ / 64) < 0)
  465. break;
  466. } else {
  467. if (NCR5380_poll_politely2(hostdata, hostdata->c400_ctl_status,
  468. CSR_HOST_BUF_NOT_RDY, 0,
  469. hostdata->c400_ctl_status,
  470. CSR_GATED_53C80_IRQ,
  471. CSR_GATED_53C80_IRQ, HZ / 64) < 0 ||
  472. NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
  473. break;
  474. }
  475. if (hostdata->io_port && hostdata->io_width == 2)
  476. insw(hostdata->io_port + hostdata->c400_host_buf,
  477. dst + start, 64);
  478. else if (hostdata->io_port)
  479. insb(hostdata->io_port + hostdata->c400_host_buf,
  480. dst + start, 128);
  481. else
  482. memcpy_fromio(dst + start,
  483. hostdata->io + NCR53C400_host_buffer, 128);
  484. start += 128;
  485. } while (start < len);
  486. residual = len - start;
  487. if (residual != 0) {
  488. /* 53c80 interrupt or transfer timeout. Reset 53c400 logic. */
  489. NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
  490. NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
  491. }
  492. wait_for_53c80_access(hostdata);
  493. if (residual == 0 && NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
  494. BASR_END_DMA_TRANSFER,
  495. BASR_END_DMA_TRANSFER,
  496. HZ / 64) < 0)
  497. scmd_printk(KERN_ERR, hostdata->connected, "%s: End of DMA timeout\n",
  498. __func__);
  499. hostdata->pdma_residual = residual;
  500. return 0;
  501. }
  502. /**
  503. * generic_NCR5380_psend - pseudo DMA send
  504. * @hostdata: scsi host private data
  505. * @src: buffer to read from
  506. * @len: transfer size
  507. *
  508. * Perform a pseudo DMA mode send to a 53C400 or equivalent device.
  509. */
  510. static inline int generic_NCR5380_psend(struct NCR5380_hostdata *hostdata,
  511. unsigned char *src, int len)
  512. {
  513. int residual;
  514. int start = 0;
  515. NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
  516. NCR5380_write(hostdata->c400_blk_cnt, len / 128);
  517. do {
  518. if (NCR5380_poll_politely2(hostdata, hostdata->c400_ctl_status,
  519. CSR_HOST_BUF_NOT_RDY, 0,
  520. hostdata->c400_ctl_status,
  521. CSR_GATED_53C80_IRQ,
  522. CSR_GATED_53C80_IRQ, HZ / 64) < 0 ||
  523. NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) {
  524. /* Both 128 B buffers are in use */
  525. if (start >= 128)
  526. start -= 128;
  527. if (start >= 128)
  528. start -= 128;
  529. break;
  530. }
  531. if (start >= len && NCR5380_read(hostdata->c400_blk_cnt) == 0)
  532. break;
  533. if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
  534. /* Host buffer is empty, other one is in use */
  535. if (start >= 128)
  536. start -= 128;
  537. break;
  538. }
  539. if (start >= len)
  540. continue;
  541. if (hostdata->io_port && hostdata->io_width == 2)
  542. outsw(hostdata->io_port + hostdata->c400_host_buf,
  543. src + start, 64);
  544. else if (hostdata->io_port)
  545. outsb(hostdata->io_port + hostdata->c400_host_buf,
  546. src + start, 128);
  547. else
  548. memcpy_toio(hostdata->io + NCR53C400_host_buffer,
  549. src + start, 128);
  550. start += 128;
  551. } while (1);
  552. residual = len - start;
  553. if (residual != 0) {
  554. /* 53c80 interrupt or transfer timeout. Reset 53c400 logic. */
  555. NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
  556. NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
  557. }
  558. wait_for_53c80_access(hostdata);
  559. if (residual == 0) {
  560. if (NCR5380_poll_politely(hostdata, TARGET_COMMAND_REG,
  561. TCR_LAST_BYTE_SENT, TCR_LAST_BYTE_SENT,
  562. HZ / 64) < 0)
  563. scmd_printk(KERN_ERR, hostdata->connected,
  564. "%s: Last Byte Sent timeout\n", __func__);
  565. if (NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
  566. BASR_END_DMA_TRANSFER, BASR_END_DMA_TRANSFER,
  567. HZ / 64) < 0)
  568. scmd_printk(KERN_ERR, hostdata->connected, "%s: End of DMA timeout\n",
  569. __func__);
  570. }
  571. hostdata->pdma_residual = residual;
  572. return 0;
  573. }
  574. static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata,
  575. struct scsi_cmnd *cmd)
  576. {
  577. int transfersize = cmd->SCp.this_residual;
  578. if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
  579. return 0;
  580. /* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */
  581. if (transfersize % 128)
  582. return 0;
  583. /* Limit PDMA send to 512 B to avoid random corruption on DTC3181E */
  584. if (hostdata->board == BOARD_DTC3181E &&
  585. cmd->sc_data_direction == DMA_TO_DEVICE)
  586. transfersize = min(cmd->SCp.this_residual, 512);
  587. return min(transfersize, DMA_MAX_SIZE);
  588. }
  589. static int generic_NCR5380_dma_residual(struct NCR5380_hostdata *hostdata)
  590. {
  591. return hostdata->pdma_residual;
  592. }
  593. /* Include the core driver code. */
  594. #include "NCR5380.c"
  595. static struct scsi_host_template driver_template = {
  596. .module = THIS_MODULE,
  597. .proc_name = DRV_MODULE_NAME,
  598. .name = "Generic NCR5380/NCR53C400 SCSI",
  599. .info = generic_NCR5380_info,
  600. .queuecommand = generic_NCR5380_queue_command,
  601. .eh_abort_handler = generic_NCR5380_abort,
  602. .eh_host_reset_handler = generic_NCR5380_host_reset,
  603. .can_queue = 16,
  604. .this_id = 7,
  605. .sg_tablesize = SG_ALL,
  606. .cmd_per_lun = 2,
  607. .use_clustering = DISABLE_CLUSTERING,
  608. .cmd_size = NCR5380_CMD_SIZE,
  609. .max_sectors = 128,
  610. };
  611. static int generic_NCR5380_isa_match(struct device *pdev, unsigned int ndev)
  612. {
  613. int ret = generic_NCR5380_init_one(&driver_template, pdev, base[ndev],
  614. irq[ndev], card[ndev]);
  615. if (ret) {
  616. if (base[ndev])
  617. printk(KERN_WARNING "Card not found at address 0x%03x\n",
  618. base[ndev]);
  619. return 0;
  620. }
  621. return 1;
  622. }
  623. static int generic_NCR5380_isa_remove(struct device *pdev,
  624. unsigned int ndev)
  625. {
  626. generic_NCR5380_release_resources(dev_get_drvdata(pdev));
  627. dev_set_drvdata(pdev, NULL);
  628. return 0;
  629. }
  630. static struct isa_driver generic_NCR5380_isa_driver = {
  631. .match = generic_NCR5380_isa_match,
  632. .remove = generic_NCR5380_isa_remove,
  633. .driver = {
  634. .name = DRV_MODULE_NAME
  635. },
  636. };
  637. #ifdef CONFIG_PNP
  638. static const struct pnp_device_id generic_NCR5380_pnp_ids[] = {
  639. { .id = "DTC436e", .driver_data = BOARD_DTC3181E },
  640. { .id = "" }
  641. };
  642. MODULE_DEVICE_TABLE(pnp, generic_NCR5380_pnp_ids);
  643. static int generic_NCR5380_pnp_probe(struct pnp_dev *pdev,
  644. const struct pnp_device_id *id)
  645. {
  646. int base, irq;
  647. if (pnp_activate_dev(pdev) < 0)
  648. return -EBUSY;
  649. base = pnp_port_start(pdev, 0);
  650. irq = pnp_irq(pdev, 0);
  651. return generic_NCR5380_init_one(&driver_template, &pdev->dev, base, irq,
  652. id->driver_data);
  653. }
  654. static void generic_NCR5380_pnp_remove(struct pnp_dev *pdev)
  655. {
  656. generic_NCR5380_release_resources(pnp_get_drvdata(pdev));
  657. pnp_set_drvdata(pdev, NULL);
  658. }
  659. static struct pnp_driver generic_NCR5380_pnp_driver = {
  660. .name = DRV_MODULE_NAME,
  661. .id_table = generic_NCR5380_pnp_ids,
  662. .probe = generic_NCR5380_pnp_probe,
  663. .remove = generic_NCR5380_pnp_remove,
  664. };
  665. #endif /* defined(CONFIG_PNP) */
  666. static int pnp_registered, isa_registered;
  667. static int __init generic_NCR5380_init(void)
  668. {
  669. int ret = 0;
  670. /* compatibility with old-style parameters */
  671. if (irq[0] == -1 && base[0] == 0 && card[0] == -1) {
  672. irq[0] = ncr_irq;
  673. base[0] = ncr_addr;
  674. if (ncr_5380)
  675. card[0] = BOARD_NCR5380;
  676. if (ncr_53c400)
  677. card[0] = BOARD_NCR53C400;
  678. if (ncr_53c400a)
  679. card[0] = BOARD_NCR53C400A;
  680. if (dtc_3181e)
  681. card[0] = BOARD_DTC3181E;
  682. if (hp_c2502)
  683. card[0] = BOARD_HP_C2502;
  684. }
  685. #ifdef CONFIG_PNP
  686. if (!pnp_register_driver(&generic_NCR5380_pnp_driver))
  687. pnp_registered = 1;
  688. #endif
  689. ret = isa_register_driver(&generic_NCR5380_isa_driver, MAX_CARDS);
  690. if (!ret)
  691. isa_registered = 1;
  692. return (pnp_registered || isa_registered) ? 0 : ret;
  693. }
  694. static void __exit generic_NCR5380_exit(void)
  695. {
  696. #ifdef CONFIG_PNP
  697. if (pnp_registered)
  698. pnp_unregister_driver(&generic_NCR5380_pnp_driver);
  699. #endif
  700. if (isa_registered)
  701. isa_unregister_driver(&generic_NCR5380_isa_driver);
  702. }
  703. module_init(generic_NCR5380_init);
  704. module_exit(generic_NCR5380_exit);