ncr810init.n
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:12k
源码类别:

VxWorks

开发平台:

C/C++

  1. ; ncr810init.n Script code for ncr810Lib Driver 
  2. ;
  3. ; Copyright 1989-1999 Wind River Systems, Inc.
  4. ;
  5. ;/*
  6. ;Modification history
  7. ;--------------------
  8. ;01b,03dec98,ihw  Modified to support concatenated IDENTIFY/normal message
  9. ;   out during activation of a new thread.  See ncr810Lib.c.
  10. ;   Removed incorrect code at ncr810InitStart - used to
  11. ;   disable reselection!  Can't do this even temporarily
  12. ;   otherwise valid reselections may not be processed. (24089)
  13. ;01a,28jun95,jds  Created. Adapted from ncr710init.n 
  14. ;
  15. ;
  16. ;INTERNAL
  17. ;To be documented...
  18. ;*/
  19. #define  NCR_COMPILE
  20. #include "drv/scsi/ncr810Script.h"
  21. ;/*****************************************************************************
  22. ;*
  23. ;* ncr810Wait - wait for re-selection by target, selection by initiator, or
  24. ;*              new command from host
  25. ;*/
  26. PROC ncr810Wait:
  27. call REL(timeoutDisable)
  28. call REL(mismatchATNIntrDisable)
  29. wait reselect REL(checkNewCmd)
  30. ;
  31. ; Have been re-selected by a SCSI target
  32. ;
  33. reselected:
  34. clear target ; required in case SIGP set
  35. move ssid to sfbr ; save target ID for ISR
  36. move sfbr to TARGET_BUS_ID
  37. ;
  38. ; Check and receive IDENTIFY message in (error if none or incorrect message)
  39. ;
  40. int NCR810_NO_IDENTIFY, when not MSG_IN ; check correct phase
  41. move from OFFSET_IDENT_IN, when MSG_IN ; read message
  42. int NCR810_NO_IDENTIFY if not 0x80 and mask 0x7f ; check for IDENTIFY
  43. move FLAGS_IDENTIFY to HOST_FLAGS
  44. int NCR810_RESELECTED ; all seems OK so far
  45. ;
  46. ; Have been selected as a target by another SCSI device.
  47. ;
  48. selected:
  49. set target ; required in case SIGP set
  50. move ssid to sfbr ; save initiator ID for ISR
  51. move sfbr to TARGET_BUS_ID
  52. ;
  53. ; Wait for SEL to be de-asserted (see NCR Device Errata Listing 135, item 2)
  54. ;
  55. selAsserted:
  56. move sbcl & SBCL_SEL to sfbr ; get state of SCSI SEL line
  57. jump REL(selAsserted) if not 0 ; loop while SEL is asserted
  58. ;
  59. ; Test whether ATN is asserted during selection
  60. ;
  61. move sbcl & SBCL_ATN to sfbr ; get state of SCSI ATN line
  62. jump REL(atnAsserted) if not 0
  63. ;
  64. ; Selection without ATN, and hence without an identification message
  65. ;
  66. move 0 to HOST_FLAGS
  67. int NCR810_SELECTED
  68. ;
  69. ; Selection with ATN - read IDENTIFY message in
  70. ;
  71. atnAsserted:
  72. move from OFFSET_IDENT_IN, with MSG_OUT ; read [sic] IDENTIFY message
  73. move FLAGS_IDENTIFY to HOST_FLAGS
  74. int NCR810_SELECTED
  75. ;
  76. ; May have a new host command to handle - check the SIGP bit
  77. ;
  78. checkNewCmd:
  79. move scntl1 & SCNTL1_CONNECTED to sfbr ; connected on SCSI bus ?
  80. jump REL(ackCmd) if 0 ; no: must be host command
  81. ; Connected - must have been selected or re-selected
  82. checkCon:
  83. move ctest2 & CTEST2_SIGNAL to sfbr ; clear SIGP bit
  84. wait reselect REL(selected) ; if target -> selected
  85. jump REL(reselected) ; else      -> reselected
  86. ;
  87. ; Should have a new host command to handle
  88. ;
  89. ackCmd:
  90. move ctest2 & CTEST2_SIGNAL to sfbr ; test and clear SIGP bit
  91. int NCR810_SPURIOUS_CMD if 0 ; if clear, spurious command
  92. int NCR810_READY ; else,     ack host command
  93. ;/*****************************************************************************
  94. ;*
  95. ;* ncr810InitStart - start new initiator thread, selecting target and
  96. ;* continuing to transfer command, data, messages as requested.
  97. ;*
  98. ;* At this point the script requires some data in the scratch registers:
  99. ;*
  100. ;* scratch 0: host flags (halt after data in, disable SCSI timeout)
  101. ;* scratch 1: message out status (none, pending, or sent)
  102. ;* scratch 2: message in  status
  103. ;* scratch 3: undefined
  104. ;*
  105. ;* When the script finishes, these registers are updated to contain:
  106. ;*
  107. ;* scratch 0: info transfer phase currently being serviced
  108. ;* scratch 1: message out status (none, pending, or sent)
  109. ;* scratch 2: message in  status
  110. ;* scratch 3: contents of LCRC reg (after a reselection)
  111. ;*/
  112. PROC ncr810InitStart:
  113. move PHASE_NONE to CURRENT_PHASE
  114. call REL(timeoutEnable)
  115. call REL(mismatchATNIntrDisable)
  116. ;
  117. ; If required to identify, select w. ATN and try to transfer IDENTIFY message
  118. ; (if this fails, continue silently).  Otherwise, select without ATN.
  119. ;
  120. move HOST_FLAGS & FLAGS_IDENTIFY to sfbr
  121. jump REL(selNoAtn) if 0
  122. select atn from OFFSET_DEVICE, REL(checkNewCmd)
  123. ; the following now transfers the IDENTIFY message plus any
  124. ; other message concatenated to it.
  125. ;
  126. ; NB this code will not tolerate phase mismatches during the message out
  127. ; transfer.  Therefore, things will go badly wrong if the target rejects
  128. ; either the IDENTIFY or the following message (for example).
  129. move from OFFSET_IDENT_OUT, when     MSG_OUT
  130. ; if there was a normal message concatenated to the IDENTIFY
  131. ; then we have now sent it.  Handle as per normal completion of MSG OUT phase.
  132. move    MSG_OUT_STATE to sfbr ; if (msg out == pending)
  133. jump    REL(doneSelect) if not M_OUT_PENDING
  134. move M_OUT_SENT to sfbr ;     msg out = sent
  135. move sfbr       to MSG_OUT_STATE
  136. jump REL(doneSelect)
  137. selNoAtn:
  138. move    0x6 to scratchb1
  139. select from OFFSET_DEVICE, REL(checkNewCmd)
  140. ; Note: must wait for any info xfer phase to be requested before proceeding
  141. ; to disable timeout.  Otherwise, the "select" appears to always hang up.
  142. jump REL(doneSelect), when not MSG_OUT
  143. ;
  144. ; Interrupt host if requested, else continue to phase-sequencing code
  145. ;
  146. doneSelect:
  147. call REL(timeoutDisable)
  148. jump REL(nextPhase)
  149. ;/*****************************************************************************
  150. ;*
  151. ;* ncr810InitContinue - resume an initiator thread
  152. ;*
  153. ;* At this point the script requires some data in the scratch registers:
  154. ;*
  155. ;* scratch 0: host flags (assert ATN on selection)
  156. ;* scratch 1: message out status (none, pending, or sent)
  157. ;* scratch 2: message in  status
  158. ;* scratch 3: undefined
  159. ;*
  160. ;* When the script finishes, these registers are updated to contain:
  161. ;*
  162. ;* scratch 0: info transfer phase currently being serviced
  163. ;* scratch 1: message out status (none, pending, or sent)
  164. ;* scratch 2: message in  status
  165. ;* scratch 3: contents of LCRC reg (after a reselection)
  166. ;*/ 
  167. PROC ncr810InitContinue:
  168. call REL(timeoutDisable)
  169. nextPhase:
  170. call REL(mismatchATNIntrEnable)
  171. move MSG_OUT_STATE  to sfbr ; if (msg out == pending)
  172. call REL(assertAtn) if M_OUT_PENDING ;     assert ATN
  173. clear ack
  174. ;
  175. ; If a message out has just been sent, and the current phase is no longer
  176. ; message out, the target has accepted the message.  Reset the message out
  177. ; state to NONE, and interrupt the host to handle msg out post-processing.
  178. ;
  179. ; XXX
  180. jump REL(phaseSwitch), when MSG_OUT ; if ((phase != msg out)
  181. move MSG_OUT_STATE     to   sfbr
  182. jump REL(phaseSwitch)  if not M_OUT_SENT ;  && (msg out == sent))
  183. move M_OUT_NONE to sfbr ;     msg out = none
  184. move sfbr       to MSG_OUT_STATE
  185. int NCR810_MESSAGE_OUT_SENT
  186. ;
  187. ; Normal info transfer request processing
  188. ;
  189. phaseSwitch:
  190. jump REL(doDataOut), when DATA_OUT
  191. jump REL(doDataIn)   if   DATA_IN
  192. jump REL(doCommand)  if   COMMAND
  193. jump REL(doStatus)   if   STATUS
  194. jump REL(doMsgOut)   if   MSG_OUT
  195. jump REL(doMsgIn)    if   MSG_IN
  196. int NCR810_ILLEGAL_PHASE
  197. ;/*****************************************************************************
  198. ;*
  199. ;* doDataOut - handle DATA OUT phase
  200. ;*/ 
  201. doDataOut:
  202. move PHASE_DATA_OUT to CURRENT_PHASE
  203. move from OFFSET_DATA, when DATA_OUT
  204. jump REL(nextPhase)
  205. ;/*****************************************************************************
  206. ;*
  207. ;* doDataIn - handle DATA IN phase
  208. ;*/ 
  209. doDataIn:
  210. move PHASE_DATA_IN to CURRENT_PHASE
  211. move from OFFSET_DATA, when DATA_IN
  212. jump REL(nextPhase)
  213. ;/*****************************************************************************
  214. ;*
  215. ;* doCommand - handle COMMAND phase
  216. ;*/ 
  217. doCommand:
  218. move PHASE_COMMAND to CURRENT_PHASE
  219. move from OFFSET_CMD, when CMD
  220. jump REL(nextPhase)
  221. ;/*****************************************************************************
  222. ;*
  223. ;* doStatus - handle STATUS phase
  224. ;*/ 
  225. doStatus:
  226. move PHASE_STATUS to CURRENT_PHASE
  227. move from OFFSET_STATUS, when STATUS
  228. jump REL(nextPhase)
  229. ;/*****************************************************************************
  230. ;*
  231. ;* doMsgOut - handle MSG OUT phase
  232. ;*/ 
  233. doMsgOut:
  234. move PHASE_MSG_OUT to CURRENT_PHASE
  235. move MSG_OUT_STATE     to sfbr ; if msg out == none
  236. int NCR810_NO_MSG_OUT if M_OUT_NONE ;     send NO-OP (host does it)
  237. call REL(assertAtn) if M_OUT_SENT ; assert ATN for retries
  238. move from OFFSET_MSG_OUT, when MSG_OUT
  239. move M_OUT_SENT to sfbr
  240. move sfbr       to MSG_OUT_STATE ; msg out = sent
  241. jump REL(nextPhase)
  242. ;/*****************************************************************************
  243. ;*
  244. ;* doMsgIn - handle MSG IN phase
  245. ;*
  246. ;* Note: there is little point in having the '810 parse the message type
  247. ;* unless it can save the host some work by doing so;  DISCONNECT and
  248. ;* COMMAND COMPLETE are really the only cases in point.  Multi-byte messages
  249. ;* are handled specially - see the comments below.
  250. ;*/ 
  251. doMsgIn:
  252. move PHASE_MSG_IN to CURRENT_PHASE
  253. move MSG_IN_STATE to sfbr
  254. jump REL(contExtMsg) if M_IN_EXT_MSG_DATA
  255. move from OFFSET_MSG_IN, when MSG_IN
  256. jump REL(twobyte)  if 0x20 and mask 0x0f
  257. jump REL(disconn)  if M_DISCONNECT
  258. jump REL(complete) if M_CMD_COMPLETE
  259. jump REL(extended) if M_EXT_MSG
  260. int NCR810_MESSAGE_IN_RECVD ; host handles all others
  261. ;
  262. ; Have received a DISCONNECT message
  263. ;
  264. disconn:
  265. move    0x00 to scntl2  ; the SDU bit needs to be cleared
  266. clear ack
  267. call REL(timeoutEnable)
  268. wait disconnect
  269. int NCR810_DISCONNECTED
  270. ;
  271. ; Have received a COMMAND COMPLETE message
  272. ;
  273. complete:
  274. move    0x00 to scntl2  ; the SDU bit needs to be cleared
  275. clear ack
  276. call REL(timeoutEnable)
  277. wait disconnect
  278. int NCR810_CMD_COMPLETE
  279. ;
  280. ; Have received the first byte of a two-byte message
  281. ;
  282. ; Read the second byte and then interrupt the host.
  283. ;
  284. twobyte:
  285. clear ack
  286. move from OFFSET_MSG_IN_SECOND, when MSG_IN
  287. int NCR810_MESSAGE_IN_RECVD
  288. ;
  289. ; Have received the first byte of an extended message
  290. ;
  291. ; Get the number of bytes in the message proper, then interrupt the host
  292. ; so it can set up the MSG_IN_REST pointer/count accordingly.  (The 53C810
  293. ; can not dynamically change this itself without having static data which
  294. ; would then need to be relocated at runtime - what a loser !)
  295. ;
  296. ; [ A "quick-and-dirty" alternative might be to set up the pointer for
  297. ; reading the message length so that it puts the byte read into the count
  298. ; field for reading the message itself.  This _should_ work, and would
  299. ; avoid interrupting the host, but seems a bit flakey. ]
  300. ;
  301. extended:
  302. clear ack
  303. move from OFFSET_MSG_IN_SECOND, when MSG_IN
  304. move M_IN_EXT_MSG_DATA to sfbr
  305. move sfbr              to MSG_IN_STATE
  306. int NCR810_EXT_MESSAGE_SIZE
  307. contExtMsg:
  308. clear ack
  309. move from OFFSET_MSG_IN_REST, when MSG_IN
  310. move M_IN_NONE to sfbr
  311. move sfbr      to MSG_IN_STATE
  312. int NCR810_MESSAGE_IN_RECVD ; at last !
  313. /******************************************************************************
  314. *
  315. * ncr810TgtDisconnect - disconnect from SCSI bus
  316. *
  317. */
  318. PROC ncr810TgtDisconnect:
  319. call REL(mismatchATNIntrDisable)
  320. set target
  321. disconnect
  322. clear target
  323. int NCR810_DISCONNECTED
  324. /******************************************************************************
  325. *
  326. * miscellaneous useful subroutines - mainly to improve readability of the
  327. * main script.  Call/return overhead is not an issue (I think).
  328. */
  329. ;
  330. ; assertAtn - assert the SCSI ATN signal
  331. ;
  332. assertAtn:
  333. set atn
  334. return
  335. ;
  336. ; timeoutEnable - enable the SCSI {inter-byte, select, disconnect} timeout
  337. ;
  338. timeoutEnable:
  339. move (STIME0_HTH_TIMEOUT | STIME0_SEL_TIMEOUT) to stime0
  340. return
  341. ;
  342. ; timeoutDisable - disable the SCSI {inter-byte, select, disconnect} timeout
  343. ;
  344. timeoutDisable:
  345. ;move (~STIME0_HTH_MASK & stime0) to stime0 ; Disable HTH timeout
  346. ;move (~STIME0_SEL_MASK & stime0) to stime0 ; Disable SEL timeout
  347. move   0x0 to sfbr
  348. move  sfbr to stime0
  349. return
  350. ;
  351. ; mismatchATNIntrEnable - enable the phase mismatch / ATN interrupt
  352. ;
  353. mismatchATNIntrEnable:
  354. move sien0 | SIEN0_MISMATCH_ATN to sfbr
  355. move sfbr to sien0
  356. return
  357. ;
  358. ; mismatchATNIntrDisable - disable the phase mismatch / ATN interrupt
  359. ;
  360. mismatchATNIntrDisable:
  361. ;move sien0 & ~SIEN0_MISMATCH_ATN to sfbr
  362. move sien0 & 0x7f to sfbr
  363. move sfbr to sien0
  364. return
  365. ; End of Script