mac53c94.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:14k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * SCSI low-level driver for the 53c94 SCSI bus adaptor found
  3.  * on Power Macintosh computers, controlling the external SCSI chain.
  4.  * We assume the 53c94 is connected to a DBDMA (descriptor-based DMA)
  5.  * controller.
  6.  *
  7.  * Paul Mackerras, August 1996.
  8.  * Copyright (C) 1996 Paul Mackerras.
  9.  */
  10. #include <linux/kernel.h>
  11. #include <linux/delay.h>
  12. #include <linux/types.h>
  13. #include <linux/string.h>
  14. #include <linux/slab.h>
  15. #include <linux/blk.h>
  16. #include <linux/proc_fs.h>
  17. #include <linux/stat.h>
  18. #include <linux/spinlock.h>
  19. #include <asm/dbdma.h>
  20. #include <asm/io.h>
  21. #include <asm/pgtable.h>
  22. #include <asm/prom.h>
  23. #include <asm/system.h>
  24. #include "scsi.h"
  25. #include "hosts.h"
  26. #include "mac53c94.h"
  27. enum fsc_phase {
  28. idle,
  29. selecting,
  30. dataing,
  31. completing,
  32. busfreeing,
  33. };
  34. struct fsc_state {
  35. volatile struct mac53c94_regs *regs;
  36. int intr;
  37. volatile struct dbdma_regs *dma;
  38. int dmaintr;
  39. int clk_freq;
  40. struct Scsi_Host *host;
  41. struct fsc_state *next;
  42. Scsi_Cmnd *request_q;
  43. Scsi_Cmnd *request_qtail;
  44. Scsi_Cmnd *current_req; /* req we're currently working on */
  45. enum fsc_phase phase; /* what we're currently trying to do */
  46. struct dbdma_cmd *dma_cmds; /* space for dbdma commands, aligned */
  47. void *dma_cmd_space;
  48. };
  49. static struct fsc_state *all_53c94s;
  50. static void mac53c94_init(struct fsc_state *);
  51. static void mac53c94_start(struct fsc_state *);
  52. static void mac53c94_interrupt(int, void *, struct pt_regs *);
  53. static void do_mac53c94_interrupt(int, void *, struct pt_regs *);
  54. static void cmd_done(struct fsc_state *, int result);
  55. static void set_dma_cmds(struct fsc_state *, Scsi_Cmnd *);
  56. static int data_goes_out(Scsi_Cmnd *);
  57. int
  58. mac53c94_detect(Scsi_Host_Template *tp)
  59. {
  60. struct device_node *node;
  61. int nfscs;
  62. struct fsc_state *state, **prev_statep;
  63. struct Scsi_Host *host;
  64. void *dma_cmd_space;
  65. unsigned char *clkprop;
  66. int proplen;
  67. nfscs = 0;
  68. prev_statep = &all_53c94s;
  69. for (node = find_devices("53c94"); node != 0; node = node->next) {
  70. if (node->n_addrs != 2 || node->n_intrs != 2)
  71. panic("53c94: expected 2 addrs and intrs (got %d/%d)",
  72.       node->n_addrs, node->n_intrs);
  73. host = scsi_register(tp, sizeof(struct fsc_state));
  74. if (host == NULL)
  75. break;
  76. host->unique_id = nfscs;
  77. #ifndef MODULE
  78. note_scsi_host(node, host);
  79. #endif
  80. state = (struct fsc_state *) host->hostdata;
  81. if (state == 0)
  82. panic("no 53c94 state");
  83. state->host = host;
  84. state->regs = (volatile struct mac53c94_regs *)
  85. ioremap(node->addrs[0].address, 0x1000);
  86. state->intr = node->intrs[0].line;
  87. state->dma = (volatile struct dbdma_regs *)
  88. ioremap(node->addrs[1].address, 0x1000);
  89. state->dmaintr = node->intrs[1].line;
  90. clkprop = get_property(node, "clock-frequency", &proplen);
  91. if (clkprop == NULL || proplen != sizeof(int)) {
  92. printk(KERN_ERR "%s: can't get clock frequencyn",
  93.        node->full_name);
  94. state->clk_freq = 25000000;
  95. } else
  96. state->clk_freq = *(int *)clkprop;
  97. /* Space for dma command list: +1 for stop command,
  98.    +1 to allow for aligning. */
  99. dma_cmd_space = kmalloc((host->sg_tablesize + 2) *
  100. sizeof(struct dbdma_cmd), GFP_KERNEL);
  101. if (dma_cmd_space == 0)
  102. panic("53c94: couldn't allocate dma command space");
  103. state->dma_cmds = (struct dbdma_cmd *)
  104. DBDMA_ALIGN(dma_cmd_space);
  105. memset(state->dma_cmds, 0, (host->sg_tablesize + 1)
  106.        * sizeof(struct dbdma_cmd));
  107. state->dma_cmd_space = dma_cmd_space;
  108. *prev_statep = state;
  109. prev_statep = &state->next;
  110. if (request_irq(state->intr, do_mac53c94_interrupt, 0,
  111. "53C94", state)) {
  112. printk(KERN_ERR "mac53C94: can't get irq %dn", state->intr);
  113. }
  114. mac53c94_init(state);
  115. ++nfscs;
  116. }
  117. return nfscs;
  118. }
  119. int
  120. mac53c94_release(struct Scsi_Host *host)
  121. {
  122. struct fsc_state *fp = (struct fsc_state *) host->hostdata;
  123. if (fp == 0)
  124. return 0;
  125. if (fp->regs)
  126. iounmap((void *) fp->regs);
  127. if (fp->dma)
  128. iounmap((void *) fp->dma);
  129. kfree(fp->dma_cmd_space);
  130. free_irq(fp->intr, fp);
  131. return 0;
  132. }
  133. int
  134. mac53c94_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
  135. {
  136. unsigned long flags;
  137. struct fsc_state *state;
  138. #if 0
  139. if (data_goes_out(cmd)) {
  140. int i;
  141. printk(KERN_DEBUG "mac53c94_queue %p: command is", cmd);
  142. for (i = 0; i < cmd->cmd_len; ++i)
  143. printk(" %.2x", cmd->cmnd[i]);
  144. printk("n" KERN_DEBUG "use_sg=%d request_bufflen=%d request_buffer=%pn",
  145.        cmd->use_sg, cmd->request_bufflen, cmd->request_buffer);
  146. }
  147. #endif
  148. cmd->scsi_done = done;
  149. cmd->host_scribble = NULL;
  150. state = (struct fsc_state *) cmd->host->hostdata;
  151. save_flags(flags);
  152. cli();
  153. if (state->request_q == NULL)
  154. state->request_q = cmd;
  155. else
  156. state->request_qtail->host_scribble = (void *) cmd;
  157. state->request_qtail = cmd;
  158. if (state->phase == idle)
  159. mac53c94_start(state);
  160. restore_flags(flags);
  161. return 0;
  162. }
  163. int
  164. mac53c94_abort(Scsi_Cmnd *cmd)
  165. {
  166. return SCSI_ABORT_SNOOZE;
  167. }
  168. int
  169. mac53c94_reset(Scsi_Cmnd *cmd, unsigned how)
  170. {
  171. struct fsc_state *state = (struct fsc_state *) cmd->host->hostdata;
  172. volatile struct mac53c94_regs *regs = state->regs;
  173. volatile struct dbdma_regs *dma = state->dma;
  174. unsigned long flags;
  175. save_flags(flags);
  176. cli();
  177. st_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
  178. regs->command = CMD_SCSI_RESET; /* assert RST */
  179. eieio();
  180. udelay(100); /* leave it on for a while (>= 25us) */
  181. regs->command = CMD_RESET;
  182. eieio();
  183. udelay(20);
  184. mac53c94_init(state);
  185. regs->command = CMD_NOP;
  186. eieio();
  187. restore_flags(flags);
  188. return SCSI_RESET_PENDING;
  189. }
  190. int
  191. mac53c94_command(Scsi_Cmnd *cmd)
  192. {
  193. printk(KERN_DEBUG "whoops... mac53c94_command calledn");
  194. return -1;
  195. }
  196. static void
  197. mac53c94_init(struct fsc_state *state)
  198. {
  199. volatile struct mac53c94_regs *regs = state->regs;
  200. volatile struct dbdma_regs *dma = state->dma;
  201. int x;
  202. regs->config1 = state->host->this_id | CF1_PAR_ENABLE;
  203. regs->sel_timeout = TIMO_VAL(250); /* 250ms */
  204. regs->clk_factor = CLKF_VAL(state->clk_freq);
  205. regs->config2 = CF2_FEATURE_EN;
  206. regs->config3 = 0;
  207. regs->sync_period = 0;
  208. regs->sync_offset = 0;
  209. eieio();
  210. x = regs->interrupt;
  211. st_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
  212. }
  213. /*
  214.  * Start the next command for a 53C94.
  215.  * Should be called with interrupts disabled.
  216.  */
  217. static void
  218. mac53c94_start(struct fsc_state *state)
  219. {
  220. Scsi_Cmnd *cmd;
  221. volatile struct mac53c94_regs *regs = state->regs;
  222. int i;
  223. if (state->phase != idle || state->current_req != NULL)
  224. panic("inappropriate mac53c94_start (state=%p)", state);
  225. if (state->request_q == NULL)
  226. return;
  227. state->current_req = cmd = state->request_q;
  228. state->request_q = (Scsi_Cmnd *) cmd->host_scribble;
  229. /* Off we go */
  230. regs->count_lo = 0;
  231. regs->count_mid = 0;
  232. regs->count_hi = 0;
  233. eieio();
  234. regs->command = CMD_NOP + CMD_DMA_MODE;
  235. udelay(1);
  236. eieio();
  237. regs->command = CMD_FLUSH;
  238. udelay(1);
  239. eieio();
  240. regs->dest_id = cmd->target;
  241. regs->sync_period = 0;
  242. regs->sync_offset = 0;
  243. eieio();
  244. /* load the command into the FIFO */
  245. for (i = 0; i < cmd->cmd_len; ++i) {
  246. regs->fifo = cmd->cmnd[i];
  247. eieio();
  248. }
  249. /* do select without ATN XXX */
  250. regs->command = CMD_SELECT;
  251. state->phase = selecting;
  252. if (cmd->use_sg > 0 || cmd->request_bufflen != 0)
  253. set_dma_cmds(state, cmd);
  254. }
  255. static void
  256. do_mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
  257. {
  258. unsigned long flags;
  259. spin_lock_irqsave(&io_request_lock, flags);
  260. mac53c94_interrupt(irq, dev_id, ptregs);
  261. spin_unlock_irqrestore(&io_request_lock, flags);
  262. }
  263. static void
  264. mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
  265. {
  266. struct fsc_state *state = (struct fsc_state *) dev_id;
  267. volatile struct mac53c94_regs *regs = state->regs;
  268. volatile struct dbdma_regs *dma = state->dma;
  269. Scsi_Cmnd *cmd = state->current_req;
  270. int nb, stat, seq, intr;
  271. static int mac53c94_errors;
  272. /*
  273.  * Apparently, reading the interrupt register unlatches
  274.  * the status and sequence step registers.
  275.  */
  276. seq = regs->seqstep;
  277. stat = regs->status;
  278. intr = regs->interrupt;
  279. #if 0
  280. printk(KERN_DEBUG "mac53c94_intr, intr=%x stat=%x seq=%x phase=%dn",
  281.        intr, stat, seq, state->phase);
  282. #endif
  283. if (intr & INTR_RESET) {
  284. /* SCSI bus was reset */
  285. printk(KERN_INFO "external SCSI bus reset detectedn");
  286. regs->command = CMD_NOP;
  287. st_le32(&dma->control, RUN << 16); /* stop dma */
  288. cmd_done(state, DID_RESET << 16);
  289. return;
  290. }
  291. if (intr & INTR_ILL_CMD) {
  292. printk(KERN_ERR "53c94: illegal cmd, intr=%x stat=%x seq=%x phase=%dn",
  293.        intr, stat, seq, state->phase);
  294. cmd_done(state, DID_ERROR << 16);
  295. return;
  296. }
  297. if (stat & STAT_ERROR) {
  298. #if 0
  299. /* XXX these seem to be harmless? */
  300. printk("53c94: bad error, intr=%x stat=%x seq=%x phase=%dn",
  301.        intr, stat, seq, state->phase);
  302. #endif
  303. ++mac53c94_errors;
  304. regs->command = CMD_NOP + CMD_DMA_MODE;
  305. eieio();
  306. }
  307. if (cmd == 0) {
  308. printk(KERN_DEBUG "53c94: interrupt with no command active?n");
  309. return;
  310. }
  311. if (stat & STAT_PARITY) {
  312. printk(KERN_ERR "mac53c94: parity errorn");
  313. cmd_done(state, DID_PARITY << 16);
  314. return;
  315. }
  316. switch (state->phase) {
  317. case selecting:
  318. if (intr & INTR_DISCONNECT) {
  319. /* selection timed out */
  320. cmd_done(state, DID_BAD_TARGET << 16);
  321. return;
  322. }
  323. if (intr != INTR_BUS_SERV + INTR_DONE) {
  324. printk(KERN_DEBUG "got intr %x during selectionn", intr);
  325. cmd_done(state, DID_ERROR << 16);
  326. return;
  327. }
  328. if ((seq & SS_MASK) != SS_DONE) {
  329. printk(KERN_DEBUG "seq step %x after commandn", seq);
  330. cmd_done(state, DID_ERROR << 16);
  331. return;
  332. }
  333. regs->command = CMD_NOP;
  334. /* set DMA controller going if any data to transfer */
  335. if ((stat & (STAT_MSG|STAT_CD)) == 0
  336.     && (cmd->use_sg > 0 || cmd->request_bufflen != 0)) {
  337. nb = cmd->SCp.this_residual;
  338. if (nb > 0xfff0)
  339. nb = 0xfff0;
  340. cmd->SCp.this_residual -= nb;
  341. regs->count_lo = nb;
  342. regs->count_mid = nb >> 8;
  343. eieio();
  344. regs->command = CMD_DMA_MODE + CMD_NOP;
  345. eieio();
  346. st_le32(&dma->cmdptr, virt_to_phys(state->dma_cmds));
  347. st_le32(&dma->control, (RUN << 16) | RUN);
  348. eieio();
  349. regs->command = CMD_DMA_MODE + CMD_XFER_DATA;
  350. state->phase = dataing;
  351. break;
  352. } else if ((stat & STAT_PHASE) == STAT_CD + STAT_IO) {
  353. /* up to status phase already */
  354. regs->command = CMD_I_COMPLETE;
  355. state->phase = completing;
  356. } else {
  357. printk(KERN_DEBUG "in unexpected phase %x after cmdn",
  358.        stat & STAT_PHASE);
  359. cmd_done(state, DID_ERROR << 16);
  360. return;
  361. }
  362. break;
  363. case dataing:
  364. if (intr != INTR_BUS_SERV) {
  365. printk(KERN_DEBUG "got intr %x before statusn", intr);
  366. cmd_done(state, DID_ERROR << 16);
  367. return;
  368. }
  369. if (cmd->SCp.this_residual != 0
  370.     && (stat & (STAT_MSG|STAT_CD)) == 0) {
  371. /* Set up the count regs to transfer more */
  372. nb = cmd->SCp.this_residual;
  373. if (nb > 0xfff0)
  374. nb = 0xfff0;
  375. cmd->SCp.this_residual -= nb;
  376. regs->count_lo = nb;
  377. regs->count_mid = nb >> 8;
  378. eieio();
  379. regs->command = CMD_DMA_MODE + CMD_NOP;
  380. eieio();
  381. regs->command = CMD_DMA_MODE + CMD_XFER_DATA;
  382. break;
  383. }
  384. if ((stat & STAT_PHASE) != STAT_CD + STAT_IO) {
  385. printk(KERN_DEBUG "intr %x before data xfer completen", intr);
  386. }
  387. st_le32(&dma->control, RUN << 16); /* stop dma */
  388. /* should check dma status */
  389. regs->command = CMD_I_COMPLETE;
  390. state->phase = completing;
  391. break;
  392. case completing:
  393. if (intr != INTR_DONE) {
  394. printk(KERN_DEBUG "got intr %x on completionn", intr);
  395. cmd_done(state, DID_ERROR << 16);
  396. return;
  397. }
  398. cmd->SCp.Status = regs->fifo; eieio();
  399. cmd->SCp.Message = regs->fifo; eieio();
  400. cmd->result = 
  401. regs->command = CMD_ACCEPT_MSG;
  402. state->phase = busfreeing;
  403. break;
  404. case busfreeing:
  405. if (intr != INTR_DISCONNECT) {
  406. printk(KERN_DEBUG "got intr %x when expected disconnectn", intr);
  407. }
  408. cmd_done(state, (DID_OK << 16) + (cmd->SCp.Message << 8)
  409.  + cmd->SCp.Status);
  410. break;
  411. default:
  412. printk(KERN_DEBUG "don't know about phase %dn", state->phase);
  413. }
  414. }
  415. static void
  416. cmd_done(struct fsc_state *state, int result)
  417. {
  418. Scsi_Cmnd *cmd;
  419. cmd = state->current_req;
  420. if (cmd != 0) {
  421. cmd->result = result;
  422. (*cmd->scsi_done)(cmd);
  423. state->current_req = NULL;
  424. }
  425. state->phase = idle;
  426. mac53c94_start(state);
  427. }
  428. /*
  429.  * Set up DMA commands for transferring data.
  430.  */
  431. static void
  432. set_dma_cmds(struct fsc_state *state, Scsi_Cmnd *cmd)
  433. {
  434. int i, dma_cmd, total;
  435. struct scatterlist *scl;
  436. struct dbdma_cmd *dcmds;
  437. dma_cmd = data_goes_out(cmd)? OUTPUT_MORE: INPUT_MORE;
  438. dcmds = state->dma_cmds;
  439. if (cmd->use_sg > 0) {
  440. total = 0;
  441. scl = (struct scatterlist *) cmd->buffer;
  442. for (i = 0; i < cmd->use_sg; ++i) {
  443. if (scl->length > 0xffff)
  444. panic("mac53c94: scatterlist element >= 64k");
  445. total += scl->length;
  446. st_le16(&dcmds->req_count, scl->length);
  447. st_le16(&dcmds->command, dma_cmd);
  448. st_le32(&dcmds->phy_addr, virt_to_phys(scl->address));
  449. dcmds->xfer_status = 0;
  450. ++scl;
  451. ++dcmds;
  452. }
  453. } else {
  454. total = cmd->request_bufflen;
  455. if (total > 0xffff)
  456. panic("mac53c94: transfer size >= 64k");
  457. st_le16(&dcmds->req_count, total);
  458. st_le32(&dcmds->phy_addr, virt_to_phys(cmd->request_buffer));
  459. dcmds->xfer_status = 0;
  460. ++dcmds;
  461. }
  462. dma_cmd += OUTPUT_LAST - OUTPUT_MORE;
  463. st_le16(&dcmds[-1].command, dma_cmd);
  464. st_le16(&dcmds->command, DBDMA_STOP);
  465. cmd->SCp.this_residual = total;
  466. }
  467. /*
  468.  * Work out whether data will be going out from the host adaptor or into it.
  469.  * (If this information is available from somewhere else in the scsi
  470.  * code, somebody please let me know :-)
  471.  */
  472. static int
  473. data_goes_out(Scsi_Cmnd *cmd)
  474. {
  475. switch (cmd->cmnd[0]) {
  476. case CHANGE_DEFINITION: 
  477. case COMPARE:   
  478. case COPY:
  479. case COPY_VERIFY:     
  480. case FORMAT_UNIT:  
  481. case LOG_SELECT:
  482. case MEDIUM_SCAN:   
  483. case MODE_SELECT:
  484. case MODE_SELECT_10:
  485. case REASSIGN_BLOCKS: 
  486. case RESERVE:
  487. case SEARCH_EQUAL:   
  488. case SEARCH_EQUAL_12: 
  489. case SEARCH_HIGH:  
  490. case SEARCH_HIGH_12:  
  491. case SEARCH_LOW:
  492. case SEARCH_LOW_12:
  493. case SEND_DIAGNOSTIC: 
  494. case SEND_VOLUME_TAG:      
  495. case SET_WINDOW: 
  496. case UPDATE_BLOCK:
  497. case WRITE_BUFFER:
  498.   case WRITE_6:
  499. case WRITE_10:
  500. case WRITE_12:   
  501. case WRITE_LONG:
  502. case WRITE_LONG_2:      /* alternate code for WRITE_LONG */
  503. case WRITE_SAME:
  504. case WRITE_VERIFY:
  505. case WRITE_VERIFY_12:
  506. return 1;
  507. default:
  508. return 0;
  509. }
  510. }
  511. static Scsi_Host_Template driver_template = SCSI_MAC53C94;
  512. #include "scsi_module.c"