g_NCR5380.c 21 KB

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