mac_scsi.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. /*
  2. * Generic Macintosh NCR5380 driver
  3. *
  4. * Copyright 1998, Michael Schmitz <mschmitz@lbl.gov>
  5. *
  6. * derived in part from:
  7. */
  8. /*
  9. * Generic Generic NCR5380 driver
  10. *
  11. * Copyright 1995, Russell King
  12. *
  13. * ALPHA RELEASE 1.
  14. *
  15. * For more information, please consult
  16. *
  17. * NCR 5380 Family
  18. * SCSI Protocol Controller
  19. * Databook
  20. *
  21. * NCR Microelectronics
  22. * 1635 Aeroplaza Drive
  23. * Colorado Springs, CO 80916
  24. * 1+ (719) 578-3400
  25. * 1+ (800) 334-5454
  26. */
  27. /*
  28. * $Log: mac_NCR5380.c,v $
  29. */
  30. #include <linux/types.h>
  31. #include <linux/stddef.h>
  32. #include <linux/ctype.h>
  33. #include <linux/delay.h>
  34. #include <linux/module.h>
  35. #include <linux/signal.h>
  36. #include <linux/sched.h>
  37. #include <linux/ioport.h>
  38. #include <linux/init.h>
  39. #include <linux/blkdev.h>
  40. #include <linux/interrupt.h>
  41. #include <asm/io.h>
  42. #include <asm/irq.h>
  43. #include <asm/system.h>
  44. #include <asm/macintosh.h>
  45. #include <asm/macints.h>
  46. #include <asm/machw.h>
  47. #include <asm/mac_via.h>
  48. #include "scsi.h"
  49. #include <scsi/scsi_host.h>
  50. #include "mac_scsi.h"
  51. #include "NCR5380.h"
  52. #if 0
  53. #define NDEBUG (NDEBUG_INTR | NDEBUG_PSEUDO_DMA | NDEBUG_ARBITRATION | NDEBUG_SELECTION | NDEBUG_RESELECTION)
  54. #else
  55. #define NDEBUG (NDEBUG_ABORT)
  56. #endif
  57. #define RESET_BOOT
  58. #define DRIVER_SETUP
  59. #define ENABLE_IRQ() mac_enable_irq( IRQ_MAC_SCSI );
  60. #define DISABLE_IRQ() mac_disable_irq( IRQ_MAC_SCSI );
  61. extern void via_scsi_clear(void);
  62. #ifdef RESET_BOOT
  63. static void mac_scsi_reset_boot(struct Scsi_Host *instance);
  64. #endif
  65. static int setup_called = 0;
  66. static int setup_can_queue = -1;
  67. static int setup_cmd_per_lun = -1;
  68. static int setup_sg_tablesize = -1;
  69. static int setup_use_pdma = -1;
  70. #ifdef SUPPORT_TAGS
  71. static int setup_use_tagged_queuing = -1;
  72. #endif
  73. static int setup_hostid = -1;
  74. /* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
  75. * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
  76. * need ten times the standard value... */
  77. #define TOSHIBA_DELAY
  78. #ifdef TOSHIBA_DELAY
  79. #define AFTER_RESET_DELAY (5*HZ/2)
  80. #else
  81. #define AFTER_RESET_DELAY (HZ/2)
  82. #endif
  83. static volatile unsigned char *mac_scsi_regp = NULL;
  84. static volatile unsigned char *mac_scsi_drq = NULL;
  85. static volatile unsigned char *mac_scsi_nodrq = NULL;
  86. /*
  87. * NCR 5380 register access functions
  88. */
  89. #if 0
  90. /* Debug versions */
  91. #define CTRL(p,v) (*ctrl = (v))
  92. static char macscsi_read(struct Scsi_Host *instance, int reg)
  93. {
  94. int iobase = instance->io_port;
  95. int i;
  96. int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
  97. CTRL(iobase, 0);
  98. i = in_8(iobase + (reg<<4));
  99. CTRL(iobase, 0x40);
  100. return i;
  101. }
  102. static void macscsi_write(struct Scsi_Host *instance, int reg, int value)
  103. {
  104. int iobase = instance->io_port;
  105. int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
  106. CTRL(iobase, 0);
  107. out_8(iobase + (reg<<4), value);
  108. CTRL(iobase, 0x40);
  109. }
  110. #else
  111. /* Fast versions */
  112. static __inline__ char macscsi_read(struct Scsi_Host *instance, int reg)
  113. {
  114. return in_8(instance->io_port + (reg<<4));
  115. }
  116. static __inline__ void macscsi_write(struct Scsi_Host *instance, int reg, int value)
  117. {
  118. out_8(instance->io_port + (reg<<4), value);
  119. }
  120. #endif
  121. /*
  122. * Function : mac_scsi_setup(char *str)
  123. *
  124. * Purpose : booter command line initialization of the overrides array,
  125. *
  126. * Inputs : str - comma delimited list of options
  127. *
  128. */
  129. static int __init mac_scsi_setup(char *str) {
  130. #ifdef DRIVER_SETUP
  131. int ints[7];
  132. (void)get_options( str, ARRAY_SIZE(ints), ints);
  133. if (setup_called++ || ints[0] < 1 || ints[0] > 6) {
  134. printk(KERN_WARNING "scsi: <mac5380>"
  135. " Usage: mac5380=<can_queue>[,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>,<use_pdma>]\n");
  136. printk(KERN_ALERT "scsi: <mac5380> Bad Penguin parameters?\n");
  137. return 0;
  138. }
  139. if (ints[0] >= 1) {
  140. if (ints[1] > 0)
  141. /* no limits on this, just > 0 */
  142. setup_can_queue = ints[1];
  143. }
  144. if (ints[0] >= 2) {
  145. if (ints[2] > 0)
  146. setup_cmd_per_lun = ints[2];
  147. }
  148. if (ints[0] >= 3) {
  149. if (ints[3] >= 0) {
  150. setup_sg_tablesize = ints[3];
  151. /* Must be <= SG_ALL (255) */
  152. if (setup_sg_tablesize > SG_ALL)
  153. setup_sg_tablesize = SG_ALL;
  154. }
  155. }
  156. if (ints[0] >= 4) {
  157. /* Must be between 0 and 7 */
  158. if (ints[4] >= 0 && ints[4] <= 7)
  159. setup_hostid = ints[4];
  160. else if (ints[4] > 7)
  161. printk(KERN_WARNING "mac_scsi_setup: invalid host ID %d !\n", ints[4] );
  162. }
  163. #ifdef SUPPORT_TAGS
  164. if (ints[0] >= 5) {
  165. if (ints[5] >= 0)
  166. setup_use_tagged_queuing = !!ints[5];
  167. }
  168. if (ints[0] == 6) {
  169. if (ints[6] >= 0)
  170. setup_use_pdma = ints[6];
  171. }
  172. #else
  173. if (ints[0] == 5) {
  174. if (ints[5] >= 0)
  175. setup_use_pdma = ints[5];
  176. }
  177. #endif /* SUPPORT_TAGS */
  178. #endif /* DRIVER_SETUP */
  179. return 1;
  180. }
  181. __setup("mac5380=", mac_scsi_setup);
  182. /*
  183. * If you want to find the instance with (k)gdb ...
  184. */
  185. #if NDEBUG
  186. static struct Scsi_Host *default_instance;
  187. #endif
  188. /*
  189. * Function : int macscsi_detect(struct scsi_host_template * tpnt)
  190. *
  191. * Purpose : initializes mac NCR5380 driver based on the
  192. * command line / compile time port and irq definitions.
  193. *
  194. * Inputs : tpnt - template for this SCSI adapter.
  195. *
  196. * Returns : 1 if a host adapter was found, 0 if not.
  197. *
  198. */
  199. int macscsi_detect(struct scsi_host_template * tpnt)
  200. {
  201. static int called = 0;
  202. int flags = 0;
  203. struct Scsi_Host *instance;
  204. if (!MACH_IS_MAC || called)
  205. return( 0 );
  206. if (macintosh_config->scsi_type != MAC_SCSI_OLD)
  207. return( 0 );
  208. /* setup variables */
  209. tpnt->can_queue =
  210. (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE;
  211. tpnt->cmd_per_lun =
  212. (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN;
  213. tpnt->sg_tablesize =
  214. (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE;
  215. if (setup_hostid >= 0)
  216. tpnt->this_id = setup_hostid;
  217. else {
  218. /* use 7 as default */
  219. tpnt->this_id = 7;
  220. }
  221. #ifdef SUPPORT_TAGS
  222. if (setup_use_tagged_queuing < 0)
  223. setup_use_tagged_queuing = USE_TAGGED_QUEUING;
  224. #endif
  225. /* Once we support multiple 5380s (e.g. DuoDock) we'll do
  226. something different here */
  227. instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
  228. #if NDEBUG
  229. default_instance = instance;
  230. #endif
  231. if (macintosh_config->ident == MAC_MODEL_IIFX) {
  232. mac_scsi_regp = via1+0x8000;
  233. mac_scsi_drq = via1+0xE000;
  234. mac_scsi_nodrq = via1+0xC000;
  235. /* The IIFX should be able to do true DMA, but pseudo-dma doesn't work */
  236. flags = FLAG_NO_PSEUDO_DMA;
  237. } else {
  238. mac_scsi_regp = via1+0x10000;
  239. mac_scsi_drq = via1+0x6000;
  240. mac_scsi_nodrq = via1+0x12000;
  241. }
  242. if (! setup_use_pdma)
  243. flags = FLAG_NO_PSEUDO_DMA;
  244. instance->io_port = (unsigned long) mac_scsi_regp;
  245. instance->irq = IRQ_MAC_SCSI;
  246. #ifdef RESET_BOOT
  247. mac_scsi_reset_boot(instance);
  248. #endif
  249. NCR5380_init(instance, flags);
  250. instance->n_io_port = 255;
  251. ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0;
  252. if (instance->irq != SCSI_IRQ_NONE)
  253. if (request_irq(instance->irq, NCR5380_intr, IRQ_FLG_SLOW,
  254. "ncr5380", instance)) {
  255. printk(KERN_WARNING "scsi%d: IRQ%d not free, interrupts disabled\n",
  256. instance->host_no, instance->irq);
  257. instance->irq = SCSI_IRQ_NONE;
  258. }
  259. printk(KERN_INFO "scsi%d: generic 5380 at port %lX irq", instance->host_no, instance->io_port);
  260. if (instance->irq == SCSI_IRQ_NONE)
  261. printk (KERN_INFO "s disabled");
  262. else
  263. printk (KERN_INFO " %d", instance->irq);
  264. printk(KERN_INFO " options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
  265. instance->can_queue, instance->cmd_per_lun, MACSCSI_PUBLIC_RELEASE);
  266. printk(KERN_INFO "\nscsi%d:", instance->host_no);
  267. NCR5380_print_options(instance);
  268. printk("\n");
  269. called = 1;
  270. return 1;
  271. }
  272. int macscsi_release (struct Scsi_Host *shpnt)
  273. {
  274. if (shpnt->irq != SCSI_IRQ_NONE)
  275. free_irq (shpnt->irq, NCR5380_intr);
  276. NCR5380_exit(shpnt);
  277. return 0;
  278. }
  279. #ifdef RESET_BOOT
  280. /*
  281. * Our 'bus reset on boot' function
  282. */
  283. static void mac_scsi_reset_boot(struct Scsi_Host *instance)
  284. {
  285. unsigned long end;
  286. NCR5380_local_declare();
  287. NCR5380_setup(instance);
  288. /*
  289. * Do a SCSI reset to clean up the bus during initialization. No messing
  290. * with the queues, interrupts, or locks necessary here.
  291. */
  292. printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
  293. /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
  294. mac_disable_irq(IRQ_MAC_SCSI);
  295. /* get in phase */
  296. NCR5380_write( TARGET_COMMAND_REG,
  297. PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
  298. /* assert RST */
  299. NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
  300. /* The min. reset hold time is 25us, so 40us should be enough */
  301. udelay( 50 );
  302. /* reset RST and interrupt */
  303. NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
  304. NCR5380_read( RESET_PARITY_INTERRUPT_REG );
  305. for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
  306. barrier();
  307. /* switch on SCSI IRQ again */
  308. mac_enable_irq(IRQ_MAC_SCSI);
  309. printk(KERN_INFO " done\n" );
  310. }
  311. #endif
  312. const char * macscsi_info (struct Scsi_Host *spnt) {
  313. return "";
  314. }
  315. /*
  316. Pseudo-DMA: (Ove Edlund)
  317. The code attempts to catch bus errors that occur if one for example
  318. "trips over the cable".
  319. XXX: Since bus errors in the PDMA routines never happen on my
  320. computer, the bus error code is untested.
  321. If the code works as intended, a bus error results in Pseudo-DMA
  322. beeing disabled, meaning that the driver switches to slow handshake.
  323. If bus errors are NOT extremely rare, this has to be changed.
  324. */
  325. #define CP_IO_TO_MEM(s,d,len) \
  326. __asm__ __volatile__ \
  327. (" cmp.w #4,%2\n" \
  328. " bls 8f\n" \
  329. " move.w %1,%%d0\n" \
  330. " neg.b %%d0\n" \
  331. " and.w #3,%%d0\n" \
  332. " sub.w %%d0,%2\n" \
  333. " bra 2f\n" \
  334. " 1: move.b (%0),(%1)+\n" \
  335. " 2: dbf %%d0,1b\n" \
  336. " move.w %2,%%d0\n" \
  337. " lsr.w #5,%%d0\n" \
  338. " bra 4f\n" \
  339. " 3: move.l (%0),(%1)+\n" \
  340. "31: move.l (%0),(%1)+\n" \
  341. "32: move.l (%0),(%1)+\n" \
  342. "33: move.l (%0),(%1)+\n" \
  343. "34: move.l (%0),(%1)+\n" \
  344. "35: move.l (%0),(%1)+\n" \
  345. "36: move.l (%0),(%1)+\n" \
  346. "37: move.l (%0),(%1)+\n" \
  347. " 4: dbf %%d0,3b\n" \
  348. " move.w %2,%%d0\n" \
  349. " lsr.w #2,%%d0\n" \
  350. " and.w #7,%%d0\n" \
  351. " bra 6f\n" \
  352. " 5: move.l (%0),(%1)+\n" \
  353. " 6: dbf %%d0,5b\n" \
  354. " and.w #3,%2\n" \
  355. " bra 8f\n" \
  356. " 7: move.b (%0),(%1)+\n" \
  357. " 8: dbf %2,7b\n" \
  358. " moveq.l #0, %2\n" \
  359. " 9: \n" \
  360. ".section .fixup,\"ax\"\n" \
  361. " .even\n" \
  362. "90: moveq.l #1, %2\n" \
  363. " jra 9b\n" \
  364. ".previous\n" \
  365. ".section __ex_table,\"a\"\n" \
  366. " .align 4\n" \
  367. " .long 1b,90b\n" \
  368. " .long 3b,90b\n" \
  369. " .long 31b,90b\n" \
  370. " .long 32b,90b\n" \
  371. " .long 33b,90b\n" \
  372. " .long 34b,90b\n" \
  373. " .long 35b,90b\n" \
  374. " .long 36b,90b\n" \
  375. " .long 37b,90b\n" \
  376. " .long 5b,90b\n" \
  377. " .long 7b,90b\n" \
  378. ".previous" \
  379. : "=a"(s), "=a"(d), "=d"(len) \
  380. : "0"(s), "1"(d), "2"(len) \
  381. : "d0")
  382. static int macscsi_pread (struct Scsi_Host *instance,
  383. unsigned char *dst, int len)
  384. {
  385. unsigned char *d;
  386. volatile unsigned char *s;
  387. NCR5380_local_declare();
  388. NCR5380_setup(instance);
  389. s = mac_scsi_drq+0x60;
  390. d = dst;
  391. /* These conditions are derived from MacOS */
  392. while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)
  393. && !(NCR5380_read(STATUS_REG) & SR_REQ))
  394. ;
  395. if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)
  396. && (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) {
  397. printk(KERN_ERR "Error in macscsi_pread\n");
  398. return -1;
  399. }
  400. CP_IO_TO_MEM(s, d, len);
  401. if (len != 0) {
  402. printk(KERN_NOTICE "Bus error in macscsi_pread\n");
  403. return -1;
  404. }
  405. return 0;
  406. }
  407. #define CP_MEM_TO_IO(s,d,len) \
  408. __asm__ __volatile__ \
  409. (" cmp.w #4,%2\n" \
  410. " bls 8f\n" \
  411. " move.w %0,%%d0\n" \
  412. " neg.b %%d0\n" \
  413. " and.w #3,%%d0\n" \
  414. " sub.w %%d0,%2\n" \
  415. " bra 2f\n" \
  416. " 1: move.b (%0)+,(%1)\n" \
  417. " 2: dbf %%d0,1b\n" \
  418. " move.w %2,%%d0\n" \
  419. " lsr.w #5,%%d0\n" \
  420. " bra 4f\n" \
  421. " 3: move.l (%0)+,(%1)\n" \
  422. "31: move.l (%0)+,(%1)\n" \
  423. "32: move.l (%0)+,(%1)\n" \
  424. "33: move.l (%0)+,(%1)\n" \
  425. "34: move.l (%0)+,(%1)\n" \
  426. "35: move.l (%0)+,(%1)\n" \
  427. "36: move.l (%0)+,(%1)\n" \
  428. "37: move.l (%0)+,(%1)\n" \
  429. " 4: dbf %%d0,3b\n" \
  430. " move.w %2,%%d0\n" \
  431. " lsr.w #2,%%d0\n" \
  432. " and.w #7,%%d0\n" \
  433. " bra 6f\n" \
  434. " 5: move.l (%0)+,(%1)\n" \
  435. " 6: dbf %%d0,5b\n" \
  436. " and.w #3,%2\n" \
  437. " bra 8f\n" \
  438. " 7: move.b (%0)+,(%1)\n" \
  439. " 8: dbf %2,7b\n" \
  440. " moveq.l #0, %2\n" \
  441. " 9: \n" \
  442. ".section .fixup,\"ax\"\n" \
  443. " .even\n" \
  444. "90: moveq.l #1, %2\n" \
  445. " jra 9b\n" \
  446. ".previous\n" \
  447. ".section __ex_table,\"a\"\n" \
  448. " .align 4\n" \
  449. " .long 1b,90b\n" \
  450. " .long 3b,90b\n" \
  451. " .long 31b,90b\n" \
  452. " .long 32b,90b\n" \
  453. " .long 33b,90b\n" \
  454. " .long 34b,90b\n" \
  455. " .long 35b,90b\n" \
  456. " .long 36b,90b\n" \
  457. " .long 37b,90b\n" \
  458. " .long 5b,90b\n" \
  459. " .long 7b,90b\n" \
  460. ".previous" \
  461. : "=a"(s), "=a"(d), "=d"(len) \
  462. : "0"(s), "1"(d), "2"(len) \
  463. : "d0")
  464. static int macscsi_pwrite (struct Scsi_Host *instance,
  465. unsigned char *src, int len)
  466. {
  467. unsigned char *s;
  468. volatile unsigned char *d;
  469. NCR5380_local_declare();
  470. NCR5380_setup(instance);
  471. s = src;
  472. d = mac_scsi_drq;
  473. /* These conditions are derived from MacOS */
  474. while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)
  475. && (!(NCR5380_read(STATUS_REG) & SR_REQ)
  476. || (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)))
  477. ;
  478. if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)) {
  479. printk(KERN_ERR "Error in macscsi_pwrite\n");
  480. return -1;
  481. }
  482. CP_MEM_TO_IO(s, d, len);
  483. if (len != 0) {
  484. printk(KERN_NOTICE "Bus error in macscsi_pwrite\n");
  485. return -1;
  486. }
  487. return 0;
  488. }
  489. /* These control the behaviour of the generic 5380 core */
  490. #define AUTOSENSE
  491. #define PSEUDO_DMA
  492. #include "NCR5380.c"
  493. static struct scsi_host_template driver_template = {
  494. .proc_name = "Mac5380",
  495. .proc_info = macscsi_proc_info,
  496. .name = "Macintosh NCR5380 SCSI",
  497. .detect = macscsi_detect,
  498. .release = macscsi_release,
  499. .info = macscsi_info,
  500. .queuecommand = macscsi_queue_command,
  501. .eh_abort_handler = macscsi_abort,
  502. .eh_bus_reset_handler = macscsi_bus_reset,
  503. .can_queue = CAN_QUEUE,
  504. .this_id = 7,
  505. .sg_tablesize = SG_ALL,
  506. .cmd_per_lun = CMD_PER_LUN,
  507. .unchecked_isa_dma = 0,
  508. .use_clustering = DISABLE_CLUSTERING
  509. };
  510. #include "scsi_module.c"