FirewireSBP2.Mod 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491
  1. MODULE FirewireSBP2;
  2. IMPORT SYSTEM, Strings, Modules, KernelLog, FirewireLow, FirewireLowUtil, Disks, Kernel,Plugins, Objects;
  3. CONST
  4. (* scsi status *)
  5. good= 0;
  6. checkCondition= 2;
  7. conditionMet= 4;
  8. busy= 8;
  9. reservationConflict= 18H;
  10. commandTerminated= 22H;
  11. NumOfOrbs= 10; (* how muchs orbs have to allocated in advance *)
  12. OrbSize= 32;
  13. NumOfBufs= 10; (* how much buffers have to be allocated in advance *)
  14. (* DataBufferSize= 1024; *)
  15. (* This address belongs to a region specified for write postings and the ohci controller will automatically send an ack
  16. when the status is written *)
  17. SBP2StatusFifoAddressHi= 0FFFEH;
  18. SBP2StatusFifoAddressLo= 0H;
  19. SBP2CSROffsetKey= 54H;
  20. SBP2UnitSpecIDKey= 12H;
  21. SBP2UnitSWVersionKey= 13H;
  22. SBP2CommandSetSpecIDKey= 38H;
  23. SBP2CommandSetKey= 39H;
  24. SBP2UnitCharKey= 3AH;
  25. SBP2DeviceTypeAndLUNKey= 14H;
  26. SBP2FirmwareRevKey= 3CH;
  27. SBP2BusyTimeOutAddrHi= 0FFFFH;
  28. SBP2BusyTimeOutAddrLo= LONGINT(0F0000210H);
  29. SBP2AgentResetData= 0FH;
  30. SBP2AgentStateOffset= 0H;
  31. SBP2AgentResetOffset= 4H;
  32. SBP2ORBPointerOffset= 8H;
  33. SBP2DoorbellOffset= 10H;
  34. SBP2UnsolStatusEnableOffset= 14H;
  35. SBP2UnsolicitedStatusValue= 0FH;
  36. LoginRequest= 0H;
  37. QueryLoginsRequest= 1H;
  38. ReconnectRequest= 3H;
  39. SetPasswordRequest= 4H;
  40. LogoutRequest= 7H;
  41. AbortTastRequest= 0BH;
  42. AbortTaskSet= 0CH;
  43. LogicalUnitReset= 0EH;
  44. TargetResetRequest= 0FH;
  45. UninitializedLUN= LONGINT(0FFFFFFFFH);
  46. BusyTimeOut = 0FH;
  47. NullPointerOrbHi= {31};
  48. NoDataTransfer= 3;
  49. DataWrite= 1;
  50. DataRead= 2;
  51. DataDirUnknown= 0;
  52. OrbDirWriteToMedia= 0H;
  53. OrbDirReadFromMedia= 1H;
  54. OrbDirNoDataTransfer = 2H;
  55. TYPE
  56. Address= RECORD
  57. value: LONGINT;
  58. next: POINTER TO Address;
  59. END;
  60. Buffer= POINTER TO ARRAY OF CHAR;
  61. Command= RECORD
  62. bufferLen: LONGINT;
  63. dataDirection: LONGINT;
  64. bufferAddr: SET;
  65. ptrToBfr: Buffer;
  66. cdb: ARRAY 12 OF CHAR; (* scsi command or sthg else *)
  67. END;
  68. Node= POINTER TO NodeDesc;
  69. NodeDesc= RECORD
  70. bufAddr: LONGINT;
  71. ptrToBfr: Buffer;
  72. next: Node;
  73. END;
  74. FIFO = RECORD
  75. first, last: Node
  76. END;
  77. FIFOList= OBJECT
  78. PROCEDURE Enqueue(VAR q: FIFO; n: Node);
  79. BEGIN
  80. n.next:= NIL;
  81. IF q.first # NIL THEN q.last.next := n ELSE q.first := n END;
  82. q.last := n;
  83. END Enqueue;
  84. PROCEDURE DequeuedNode(VAR q: FIFO): Node;
  85. VAR n: Node;
  86. BEGIN
  87. n := q.first;
  88. IF n # NIL THEN q.first := n.next END;
  89. RETURN n
  90. END DequeuedNode;
  91. END FIFOList;
  92. BufferFIFO= OBJECT
  93. VAR q: FIFO; list: FIFOList; usedQ: FIFO; usedList: FIFOList; bufSize: LONGINT;
  94. owner : ANY;
  95. PROCEDURE GetBuffer(VAR ptrToBfr: Buffer):LONGINT;
  96. VAR n:Node;
  97. BEGIN {EXCLUSIVE}
  98. n:=list.DequeuedNode(q); (* Print(debug,"Dequeuning node"); *)
  99. IF n = NIL THEN (* Print(debug,"Allocating new buffer!"); *)
  100. NEW(n); n.bufAddr:= SYSTEM.VAL(LONGINT,AllocBuf(bufSize,n.ptrToBfr))
  101. END;
  102. usedList.Enqueue(usedQ,n);
  103. (* Print(debug,"Returning address!");
  104. KernelLog.Int(n.bufAddr,2); *)
  105. ASSERT(n.bufAddr > 0);
  106. ptrToBfr:= n.ptrToBfr;
  107. RETURN n.bufAddr;
  108. END GetBuffer;
  109. PROCEDURE ReleaseBuffer(ptrToBfr: Buffer; bufAddr: LONGINT);
  110. VAR n: Node;
  111. BEGIN {EXCLUSIVE}
  112. ASSERT(bufAddr > 0);
  113. n:= usedList.DequeuedNode(usedQ);
  114. (* Be aware that n.bufAddr, will not necessarily point to the same buffer as n.ptrToBfr *)
  115. n.bufAddr:= bufAddr;
  116. n.ptrToBfr:= ptrToBfr;
  117. ASSERT(n.bufAddr > 0);
  118. list.Enqueue(q,n);
  119. END ReleaseBuffer;
  120. PROCEDURE &Init*(numOfBuf,bufSize: LONGINT);
  121. VAR n: Node;i: LONGINT;
  122. BEGIN {EXCLUSIVE}
  123. NEW(list); NEW(usedList); SELF.bufSize:= bufSize;
  124. IF numOfBuf > 0 THEN
  125. FOR i:= 0 TO numOfBuf-1 DO
  126. NEW(n);
  127. n.bufAddr:= SYSTEM.VAL(LONGINT,AllocBuf(bufSize,n.ptrToBfr));
  128. list.Enqueue(q,n)
  129. END
  130. END
  131. END Init;
  132. END BufferFIFO;
  133. (** The SBP2 fireWire device *)
  134. Sbp2Dev= OBJECT(Disks.Device)
  135. VAR
  136. DataBufferSize: LONGINT;
  137. id*: LONGINT;
  138. speedCode*: LONGINT;
  139. mgmtAgntAddrLow*: SET;
  140. mgmtAgntAddrHigh*: SET;
  141. cmdBlckAgntAddrLow*: SET;
  142. cmdBlckAgntAddrHigh*: SET;
  143. lastOrb: Sbp2CommandOrb;
  144. loginOrb: Sbp2LoginOrb;
  145. loginResp: Sbp2LoginResponse;
  146. queryLogins: Sbp2QueryLoginsOrb;
  147. queryLoginsResp: Sbp2QueryLoginsResp;
  148. reconnectOrb: Sbp2ReconnectOrb;
  149. logoutOrb: Sbp2LogoutOrb;
  150. statusBlock: Sbp2StatusBlock;
  151. maxPayload*: LONGINT;
  152. commandSetSpecID*: LONGINT;
  153. commandSet*: LONGINT;
  154. unitChar*: SET;
  155. logicalUnitNumber*: SET;
  156. firmwareRev*: LONGINT;
  157. loginComplete*: BOOLEAN;
  158. nodeEntry*: FirewireLowUtil.Node;
  159. commandOrbFIFO*: BufferFIFO;
  160. dataBufferFIFO*: BufferFIFO;
  161. t: Kernel.Timer;
  162. PROCEDURE Config;
  163. VAR size, diskres,payloadNotCoded: LONGINT;
  164. BEGIN
  165. payloadNotCoded:= SYSTEM.VAL(LONGINT,LSH({0},maxPayload+1));
  166. NEW(dataBufferFIFO,10,payloadNotCoded);
  167. NEW(commandOrbFIFO,NumOfOrbs,OrbSize);
  168. GetSize(size,diskres);
  169. DataBufferSize:= blockSize;
  170. END Config;
  171. PROCEDURE CreateCommandOrb(VAR commandOrb: Sbp2CommandOrb; VAR command: Command);
  172. VAR dataBufAddr,addr,direction,i,numOfOrbs,payloadNotCoded: LONGINT;
  173. BEGIN
  174. commandOrb.nextOrbHi:= NullPointerOrbHi;
  175. commandOrb.nextOrbLo:= {};
  176. (* set the max payload *)
  177. commandOrb.misc:= LSH(SYSTEM.VAL(SET,maxPayload),20);
  178. (* set the speed *)
  179. commandOrb.misc:= commandOrb.misc + LSH(SYSTEM.VAL(SET,speedCode),24);
  180. (* set the notify speed *)
  181. commandOrb.misc:= commandOrb.misc + {31};
  182. (* set the page size *)
  183. commandOrb.misc:= commandOrb.misc + {17};
  184. dataBufAddr:= dataBufferFIFO.GetBuffer(commandOrb.ptrToDataBfr);
  185. host.adrCheck.Add(dataBufAddr);
  186. ASSERT(dataBufAddr > 0);
  187. (* Print(debug,"Printing the data buffer address");
  188. KernelLog.Int(dataBufAddr,2); *)
  189. CASE command.dataDirection OF
  190. NoDataTransfer: direction:= OrbDirNoDataTransfer;
  191. |DataWrite: direction:= OrbDirWriteToMedia;
  192. |DataRead: direction:= OrbDirReadFromMedia;
  193. ELSE direction:= OrbDirNoDataTransfer; Print(debug,"Data direction is unknown");
  194. END;
  195. IF direction = OrbDirNoDataTransfer THEN
  196. Print(debug,"No data transfer!::CrateCommandOrb");
  197. commandOrb.dataDescHi:= {}; commandOrb.dataDescLo:= {};
  198. commandOrb.misc:= commandOrb.misc + {27};
  199. ELSE
  200. (* set the direction *)
  201. commandOrb.misc:= commandOrb.misc + SYSTEM.VAL(SET,LSH(direction,27));
  202. (* check how big the buffer has to be *)
  203. (* KernelLog.Int(maxPayload,2);KernelLog.Ln(); *)
  204. payloadNotCoded:= SYSTEM.VAL(LONGINT,LSH({0},maxPayload+1));
  205. (* KernelLog.Int(payloadNotCoded,2); *)
  206. numOfOrbs:= command.bufferLen DIV payloadNotCoded;
  207. ASSERT(numOfOrbs <= 1);
  208. (* set the data size *)
  209. commandOrb.misc:= commandOrb.misc + SYSTEM.VAL(SET,command.bufferLen);
  210. (* set the buffer address *)
  211. commandOrb.dataDescHi:= LSH(FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{0..15},16);
  212. commandOrb.dataDescLo:= SYSTEM.VAL(SET,dataBufAddr);
  213. ASSERT(~(31 IN commandOrb.dataDescLo));
  214. FOR i:= 0 TO 11 DO
  215. commandOrb.cdb[i]:= command.cdb[i];
  216. END;
  217. (* copy the data into a buffer *)
  218. ASSERT( dataBufAddr > 0);
  219. IF direction = OrbDirWriteToMedia THEN
  220. ASSERT((command.bufferLen MOD 4) = 0);
  221. ASSERT(command.bufferLen <= 1024);
  222. FOR i:= 0 TO (command.bufferLen DIV 4)-1 DO
  223. SYSTEM.PUT32(dataBufAddr+i*4,SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)+i*4));
  224. END;
  225. ELSE command.bufferAddr:= SYSTEM.VAL(SET,dataBufAddr)
  226. END;
  227. (* Now copy the commandOrb into a buffer *)
  228. commandOrb.bufAddr:= SYSTEM.VAL(SET,commandOrbFIFO.GetBuffer(commandOrb.ptrToBfr));
  229. addr:= SYSTEM.VAL(LONGINT,commandOrb.bufAddr);
  230. ASSERT(addr > 0);
  231. SYSTEM.PUT32(addr,SYSTEM.VAL(LONGINT,commandOrb.nextOrbHi));
  232. SYSTEM.PUT32(addr+4,SYSTEM.VAL(LONGINT,commandOrb.nextOrbLo));
  233. SYSTEM.PUT32(addr+8,SYSTEM.VAL(LONGINT,commandOrb.dataDescHi));
  234. SYSTEM.PUT32(addr+12,SYSTEM.VAL(LONGINT,commandOrb.dataDescLo));
  235. SYSTEM.PUT32(addr+16,SYSTEM.VAL(LONGINT,commandOrb.misc));
  236. (* byte swap the command orb *)
  237. InvertByteOrder(addr,32);
  238. SYSTEM.PUT8(addr+20,commandOrb.cdb[0]);
  239. SYSTEM.PUT8(addr+21,commandOrb.cdb[1]);
  240. SYSTEM.PUT8(addr+22,commandOrb.cdb[2]);
  241. SYSTEM.PUT8(addr+23,commandOrb.cdb[3]);
  242. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+20))); *)
  243. SYSTEM.PUT8(addr+24,commandOrb.cdb[4]);
  244. SYSTEM.PUT8(addr+25,commandOrb.cdb[5]);
  245. SYSTEM.PUT8(addr+26,commandOrb.cdb[6]);
  246. SYSTEM.PUT8(addr+27,commandOrb.cdb[7]);
  247. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+24))); *)
  248. SYSTEM.PUT8(addr+28,commandOrb.cdb[8]);
  249. SYSTEM.PUT8(addr+29,commandOrb.cdb[9]);
  250. SYSTEM.PUT8(addr+30,commandOrb.cdb[10]);
  251. SYSTEM.PUT8(addr+31,commandOrb.cdb[11]);
  252. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+28))); *)
  253. END
  254. END CreateCommandOrb;
  255. PROCEDURE LinkCommandOrb(commandOrb: Sbp2CommandOrb;VAR diskres: LONGINT);
  256. VAR buffer: ARRAY 2 OF SET; quadlet: SET;
  257. BEGIN
  258. diskres:= 0;
  259. (* Print(debug,"Printing the buffer Address of the last orb");
  260. FirewireLowUtil.PrintSet(lastOrb.bufAddr); *)
  261. IF lastOrb.bufAddr = {} THEN
  262. (* let's write to the targets management agent register to to set the orb pointer offset *)
  263. (* Print(debug,"Setting the orb pointer offset"); *)
  264. buffer[0]:= {};
  265. buffer[1]:= commandOrb.bufAddr;
  266. (* swap bytes *)
  267. InvertByteOrderWord(buffer[1]);
  268. IF ~HpsbNodeWrite(nodeEntry,cmdBlckAgntAddrLow+SYSTEM.VAL(SET,SBP2ORBPointerOffset),
  269. cmdBlckAgntAddrHigh , SYSTEM.VAL(SET,ADDRESSOF(buffer)), 8) THEN diskres:= 1;
  270. Print(debug,"Setting the orb pointer failed");
  271. END;
  272. lastOrb.bufAddr:= commandOrb.bufAddr;
  273. lastOrb.ptrToBfr:= commandOrb.ptrToBfr;
  274. lastOrb.dataDescLo:= commandOrb.dataDescLo;
  275. lastOrb.ptrToDataBfr:= commandOrb.ptrToDataBfr;
  276. (* Print(debug,"Printing the buffer Address of the last orb");
  277. FirewireLowUtil.PrintSet(lastOrb.bufAddr); *)
  278. ELSE (* the orb pointer is already set *)
  279. SYSTEM.PUT32(SYSTEM.VAL(LONGINT,lastOrb.bufAddr),0);
  280. SYSTEM.PUT32(SYSTEM.VAL(LONGINT,lastOrb.bufAddr)+4,SYSTEM.VAL(LONGINT,commandOrb.bufAddr));
  281. (* swap bytes *)
  282. InvertByteOrder(SYSTEM.VAL(LONGINT,lastOrb.bufAddr)+4,4);
  283. (* release buffer *)
  284. commandOrbFIFO.ReleaseBuffer(lastOrb.ptrToBfr,SYSTEM.VAL(LONGINT,lastOrb.bufAddr));
  285. dataBufferFIFO.ReleaseBuffer(lastOrb.ptrToDataBfr,SYSTEM.VAL(LONGINT,lastOrb.dataDescLo));
  286. lastOrb.bufAddr:= commandOrb.bufAddr;
  287. lastOrb.ptrToBfr:= commandOrb.ptrToBfr;
  288. lastOrb.dataDescLo:= commandOrb.dataDescLo;
  289. lastOrb.ptrToDataBfr:= commandOrb.ptrToDataBfr;
  290. (* ring the doorbell *)
  291. (* Print(debug,"Ringing the doorbell"); *)
  292. quadlet:= commandOrb.bufAddr;
  293. (* it's not important what we write in the doorbell register *)
  294. IF ~HpsbNodeWrite(nodeEntry,cmdBlckAgntAddrLow+SYSTEM.VAL(SET,SBP2DoorbellOffset),
  295. cmdBlckAgntAddrHigh ,quadlet , 4) THEN diskres:= 1;
  296. Print(debug,"Ringing the doorbell failed");
  297. END
  298. END
  299. END LinkCommandOrb;
  300. PROCEDURE HandleStatus(statusBufAddr: LONGINT);
  301. VAR statusHi: SET; length: LONGINT; scsiStatus: LONGINT;
  302. BEGIN
  303. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(statusBufAddr));
  304. (* Check if target stored any scsi status information, check the length *)
  305. length:= SYSTEM.VAL(LONGINT,LSH(statusHi,-24)*{0..2});
  306. IF length > 1 THEN (* there is scsi sense data, something went wrong *)
  307. ELSE scsiStatus:= good; (* for future use *)
  308. END;
  309. (* check to see if the dead bit is set *)
  310. IF 27 IN SYSTEM.VAL(SET,SYSTEM.GET32(statusBufAddr)) THEN (* do an agent reset *)
  311. KernelLog.String("The dead bit is set, doing an agent reset!"); KernelLog.Ln();
  312. AgentReset(SELF);
  313. END;
  314. (*
  315. KernelLog.String("Printing the status: "); KernelLog.Ln();
  316. FirewireLowUtil.PrintSet(statusHi);
  317. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(statusBufAddr+4)));
  318. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(statusBufAddr+8)));
  319. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(statusBufAddr+12))); *)
  320. IF ({28,29}*statusHi # {}) OR (27 IN statusHi) OR ({16..23}* statusHi # {}) THEN
  321. KernelLog.String("There was an error sending the command!"); KernelLog.Ln();
  322. ELSE (* Print(debug,"There was no error sending the command!"); KernelLog.Ln(); *)
  323. END;
  324. (* resetting the status *)
  325. SYSTEM.PUT32(statusBufAddr,{});
  326. END HandleStatus;
  327. PROCEDURE SendCommand(VAR command: Command;VAR diskres: LONGINT): BOOLEAN;
  328. VAR
  329. commandOrb: Sbp2CommandOrb;i,addr,retBufferAddr : LONGINT; (* t: Kernel.Timer; *)
  330. statusHi,statusLow: SET;
  331. milliTimer : Kernel.MilliTimer;
  332. BEGIN
  333. (* remember return buffer address *)
  334. (* Print(debug,"Printing the return buffer address");
  335. FirewireLowUtil.PrintSet(command.bufferAddr); *)
  336. retBufferAddr:= SYSTEM.VAL(LONGINT,command.bufferAddr);
  337. (* ASSERT(retBufferAddr > 0); *)
  338. (* KernelLog.String("Printing commandOrb.cdb: "); KernelLog.Int(ADDRESSOF(commandOrb.cdb),2); KernelLog.Ln();
  339. ASSERT(ADDRESSOF(commandOrb.cdb) > 0); *)
  340. (* Print(debug,"Printing the return buffer address");
  341. KernelLog.Int(retBufferAddr,2); *)
  342. (* fill the command orb *)
  343. CreateCommandOrb(commandOrb,command);
  344. (* initialize status block *)
  345. FOR i:= 0 TO 7 DO
  346. SYSTEM.PUT32(SYSTEM.VAL(LONGINT,statusBlock.bufAddr)+i*4,0);
  347. END;
  348. (* link up the orb and ring the doorbell *)
  349. LinkCommandOrb(commandOrb,diskres);
  350. (* wait for the status *)
  351. addr:= SYSTEM.VAL(LONGINT,statusBlock.bufAddr);
  352. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  353. statusLow:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
  354. Kernel.SetTimer(milliTimer, 120000); (* Wait for two min *)
  355. i:= 0;
  356. WHILE ((statusHi = {}) OR (statusLow = {})) & ~Kernel.Expired(milliTimer) DO
  357. Objects.Yield(); statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  358. statusLow:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
  359. END;
  360. IF (statusHi = {}) & (statusLow = {}) THEN Print(debug,"Error: Received no status!"); diskres:= -1; RETURN FALSE
  361. ELSE HandleStatus(addr)
  362. END;
  363. IF command.dataDirection = DataRead THEN
  364. ASSERT((blockSize MOD 4)=0);
  365. FOR i:= 0 TO (command.bufferLen DIV 4)-1 DO
  366. SYSTEM.PUT32(retBufferAddr+i*4,SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)+i*4))
  367. END;
  368. InvertByteOrder(retBufferAddr,command.bufferLen);
  369. END;
  370. RETURN TRUE;
  371. END SendCommand;
  372. PROCEDURE Handle *(VAR msg: Disks.Message; VAR diskres: LONGINT);
  373. (* VAR command: Command; cylinders,heads,sectors,i: LONGINT; *)
  374. BEGIN
  375. KernelLog.String("HANDLE"); KernelLog.Ln;
  376. diskres := Disks.Unsupported;
  377. (* IF msg IS Disks.GetGeometryMsg THEN Print(debug,"It's a geometry message request!");
  378. msg(Disks.GetGeometryMsg).spt:= 18; msg(Disks.GetGeometryMsg).hds := 2; msg(Disks.GetGeometryMsg).cyls := 80;
  379. build IDENTIFY DRIVE command
  380. command.bufferAddr:= AllocBuf(1024,command.ptrToBfr);
  381. command.bufferLen:= 1024;
  382. command.dataDirection:= DataRead;
  383. (* UFI: IDENTIFY DRIVE command *)
  384. FOR i:= 0 TO 11 DO command.cdb[i] := CHR(0); END;
  385. command.cdb[0] := 0ECX;
  386. IF ~SendCommand(command,diskres) THEN END;
  387. IF (diskres # Disks.Ok) THEN RETURN; END;
  388. cylinders:= SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)+1);
  389. heads:= SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)+3);
  390. sectors:= SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)+6);
  391. Print(debug,"cylinders: "); KernelLog.Int(cylinders,2); KernelLog.Ln();
  392. Print(debug,"cylinders: "); KernelLog.Int(heads,2); KernelLog.Ln();
  393. Print(debug,"cylinders: "); KernelLog.Int(sectors,2); KernelLog.Ln();
  394. ELSE Print(debug,"Message unknown!")
  395. END; *)
  396. SELF.blockSize:= 512;
  397. (* KernelLog.Int(SELF.blockSize,2); *)
  398. END Handle;
  399. PROCEDURE Transfer*(op,block,num: LONGINT; VAR data: ARRAY OF CHAR; ofs: LONGINT; VAR diskres: LONGINT);
  400. VAR i, payloadNotCoded: LONGINT; command: Command; numOfBlocks,tries: LONGINT;
  401. BEGIN
  402. tries:= 0;
  403. payloadNotCoded:= SYSTEM.VAL(LONGINT,LSH({0},maxPayload+1));
  404. numOfBlocks:= payloadNotCoded DIV blockSize;
  405. FOR i:= 0 TO 11 DO command.cdb[i]:= CHR(0) END;
  406. IF (op = Disks.Read) OR (op = Disks.Write) THEN
  407. IF op = Disks.Read THEN
  408. command.cdb[0]:= 28X; command.dataDirection:= DataRead
  409. ELSE
  410. command.cdb[0]:= 2AX; command.dataDirection:= DataWrite
  411. END;
  412. i:= 0;
  413. WHILE num > 0 DO
  414. IF numOfBlocks < num THEN command.bufferLen:= numOfBlocks*blockSize;
  415. ELSE command.bufferLen:= num*blockSize; numOfBlocks:= num;
  416. END;
  417. command.bufferAddr:= SYSTEM.VAL(SET,ADDRESSOF(data[0])+ofs+i*blockSize);
  418. command.cdb[2]:= CHR(LSH(block,-24));
  419. command.cdb[3]:= CHR(LSH(block,-16));
  420. command.cdb[4]:= CHR(LSH(block,-8));
  421. command.cdb[5]:= CHR(block);
  422. (* command.cdb[7]:= CHR(LSH(num,-8));
  423. command.cdb[8]:= CHR(num); *)
  424. command.cdb[7]:= CHR(LSH(numOfBlocks,-8));
  425. command.cdb[8]:= CHR(numOfBlocks);
  426. IF ~SendCommand(command, diskres) THEN
  427. IF tries > 10 THEN RETURN ELSE INC(tries); END;
  428. ELSE
  429. IF diskres # Disks.Ok THEN RETURN
  430. END;
  431. tries:= 0;
  432. INC(block,numOfBlocks); DEC(num,numOfBlocks); INC(i,numOfBlocks);
  433. END;
  434. END
  435. ELSE
  436. diskres:= Disks.Unsupported;
  437. END;
  438. END Transfer;
  439. PROCEDURE GetSize*(VAR size: LONGINT;VAR diskres: LONGINT);
  440. VAR command: Command; i: LONGINT; (* dev: Sbp2Dev; *)
  441. BEGIN
  442. command.bufferAddr:= AllocBuf(1024,command.ptrToBfr);
  443. command.bufferLen:= 1024;
  444. command.dataDirection:= DataRead;
  445. (* UFI: Read Capacity command *)
  446. FOR i:= 0 TO 11 DO command.cdb[i] := CHR(0); END;
  447. command.cdb[0] := 25X;
  448. IF ~SendCommand(command,diskres) THEN END;
  449. IF (diskres # Disks.Ok) THEN RETURN; END;
  450. size:= SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr));
  451. blockSize:= SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)+4);
  452. INC (size);
  453. diskres := Disks.Ok;
  454. (* KernelLog.String(" Disk info: Blocks: "); KernelLog.Int(size, 0);
  455. KernelLog.String(" blocksize: "); KernelLog.Int(blockSize,0);
  456. KernelLog.String(" size: "); KernelLog.Int(size*blockSize,0);
  457. KernelLog.String(" size in giga: "); KernelLog.Int(((size DIV 1024)*(blockSize)) DIV (1024*1024),0);
  458. KernelLog.Ln; *)
  459. END GetSize;
  460. PROCEDURE &Init*;
  461. BEGIN
  462. (* set default *) blockSize:= 512; NEW(t);
  463. END Init;
  464. END Sbp2Dev;
  465. SbpDevGrp= ARRAY 64 OF Sbp2Dev;
  466. Sbp2StatusBlock*= RECORD
  467. orbOffsetHi: SET;
  468. orbOffsetLo: SET;
  469. commandSetDependent: ARRAY 24 OF CHAR;
  470. bufAddr: SET;
  471. ptrToBfr: Buffer;
  472. END;
  473. Sbp2LoginOrb*= RECORD
  474. passwordHi: LONGINT;
  475. passwordLo: LONGINT;
  476. loginRespHi: LONGINT;
  477. loginRespLo: LONGINT;
  478. lunMisc: SET;
  479. passwrdRespLens: LONGINT;
  480. statusFIFOHi: SET;
  481. statusFIFOLo: SET;
  482. bufAddr: SET;
  483. ptrToBfr: Buffer;
  484. END;
  485. Sbp2LoginResponse*= RECORD
  486. lenLoginID: LONGINT;
  487. commandBlckAgntHi: SET;
  488. commandBlckAgntLo: SET;
  489. reconnectHold: SET;
  490. bufAddr: SET;
  491. ptrToBfr: Buffer;
  492. END;
  493. Sbp2QueryLoginsOrb*= RECORD
  494. reserved1: LONGINT;
  495. reserved2: LONGINT;
  496. queryRespHi: SET;
  497. queryRespLo: SET;
  498. lunMisc: SET;
  499. reservedRespLen: LONGINT;
  500. statusFIFOHi: SET;
  501. statusFIFOLo: SET;
  502. bufAddr: SET;
  503. ptrToBfr: Buffer;
  504. END;
  505. Sbp2QueryLoginsResp*= RECORD
  506. lenMaxLogins: LONGINT;
  507. miscIDs: SET;
  508. initiatorMiscHi: LONGINT;
  509. initiatorMiscLo: LONGINT;
  510. bufAddr: SET;
  511. ptrToBfr: Buffer;
  512. END;
  513. Sbp2ReconnectOrb*= RECORD
  514. reserved1: LONGINT;
  515. reserved2: LONGINT;
  516. reserved3: LONGINT;
  517. reserved4: LONGINT;
  518. loginIDMisc: SET;
  519. reserved5: LONGINT;
  520. statusFIFOHi: SET;
  521. statusFIFOLo: SET;
  522. bufAddr: SET;
  523. ptrToBfr: Buffer;
  524. END;
  525. Sbp2LogoutOrb*= RECORD
  526. reserved1: LONGINT;
  527. reserved2: LONGINT;
  528. reserved3: LONGINT;
  529. reserved4: LONGINT;
  530. loginIDMisc: SET;
  531. reserved5: LONGINT;
  532. statusFIFOHi: SET;
  533. statusFIFOLo: SET;
  534. bufAddr: SET;
  535. ptrToBfr: Buffer;
  536. END;
  537. Sbp2CommandOrb*= RECORD
  538. nextOrbHi: SET;
  539. nextOrbLo: SET;
  540. dataDescHi: SET;
  541. dataDescLo: SET;
  542. ptrToDataBfr: Buffer;
  543. misc: SET;
  544. cdb: ARRAY 12 OF CHAR;
  545. bufAddr: SET;
  546. ptrToBfr: Buffer;
  547. END;
  548. Sbp2CommandInfo*= RECORD
  549. command: Sbp2CommandOrb;
  550. dataDirection: LONGINT;
  551. END;
  552. VAR
  553. debug: BOOLEAN;
  554. sbpDevGrps: ARRAY 63 OF SbpDevGrp; (* This should be updated if the driver has to scan more than one bus *)
  555. numOfGrps: LONGINT;
  556. host: FirewireLowUtil.OHCIDesc;
  557. (** Set the maximum speed and payload size for a new identified device *)
  558. PROCEDURE MaxSpeedAndSize(VAR dev: Sbp2Dev);
  559. BEGIN
  560. (* Print(debug,"Setting max speed and payload size"); *)
  561. dev.speedCode:= host.SpeedMap[host.nodeID][SYSTEM.VAL(LONGINT,dev.nodeEntry.phyID)];
  562. IF ConvertSpeedToPayload(dev.speedCode) > ConvertPayloadToMaxRec(host.MaxPacketSize) THEN
  563. dev.maxPayload:= ConvertPayloadToMaxRec(host.MaxPacketSize)
  564. ELSE dev.maxPayload:= ConvertSpeedToPayload(dev.speedCode)
  565. END;
  566. (* KernelLog.Int(dev.speedCode,2); KernelLog.Ln();
  567. KernelLog.Int(dev.maxPayload,2); KernelLog.Ln(); *)
  568. END MaxSpeedAndSize;
  569. PROCEDURE AgentReset(dev: Sbp2Dev);
  570. VAR quadlet: SET;
  571. BEGIN
  572. (* Print(debug,"Doing an agent reset"); *)
  573. quadlet:= SYSTEM.VAL(SET,SBP2AgentResetData);
  574. IF ~HpsbNodeWrite(dev.nodeEntry,
  575. dev.cmdBlckAgntAddrLow+SYSTEM.VAL(SET,SBP2AgentResetOffset),dev.cmdBlckAgntAddrHigh,quadlet,4) THEN
  576. Print(debug,"Resetting the agent failed");
  577. END;
  578. END AgentReset;
  579. PROCEDURE SetBusyTimeOut(ne: FirewireLowUtil.Node);
  580. VAR quadlet: SET;
  581. BEGIN
  582. (* Print(debug,"Setting busy time out"); *)
  583. quadlet:= SYSTEM.VAL(SET,BusyTimeOut);
  584. InvertByteOrderWord(quadlet);
  585. IF ~HpsbNodeWrite(ne,SYSTEM.VAL(SET,SBP2BusyTimeOutAddrLo),
  586. SYSTEM.VAL(SET,SBP2BusyTimeOutAddrHi),quadlet,4) THEN
  587. Print(debug,"Setting the busy time out failed");
  588. END;
  589. END SetBusyTimeOut;
  590. PROCEDURE InvertByteOrderWord(VAR word: SET);
  591. VAR swapWord: SET;
  592. BEGIN
  593. swapWord:= LSH(word*{0..7},24);
  594. swapWord:= swapWord +LSH(word*{8..15},8);
  595. swapWord:= swapWord +LSH(word*{16..23},-8);
  596. swapWord:= swapWord +LSH(word*{24..31},-24);
  597. word:= swapWord;
  598. END InvertByteOrderWord;
  599. (*
  600. PROCEDURE InvertByteOrderBuf(VAR buffer: ARRAY OF SET; length: LONGINT);
  601. VAR numOfWords, i: LONGINT; quadlet,quadletSwap: SET;
  602. BEGIN
  603. numOfWords:= length DIV 4; i:= 0; length:= 0;
  604. WHILE i # numOfWords DO
  605. quadlet:= buffer[i];
  606. (* FirewireLowUtil.PrintSet(quadlet); *)
  607. quadletSwap:= LSH(quadlet*{0..7},24);
  608. quadletSwap:= quadletSwap+LSH(quadlet*{8..15},8);
  609. quadletSwap:= quadletSwap+LSH(quadlet*{16..23},-8);
  610. quadletSwap:= quadletSwap+LSH(quadlet*{24..31},-24);
  611. (* FirewireLowUtil.PrintSet(quadletSwap); *)
  612. buffer[i]:= quadletSwap;
  613. INC(i);
  614. END;
  615. END InvertByteOrderBuf;
  616. *)
  617. PROCEDURE InvertByteOrder(bufAddr: LONGINT; length: LONGINT);
  618. VAR numOfWords, i: LONGINT; quadlet,quadletSwap: SET;
  619. BEGIN
  620. numOfWords:= length DIV 4; i:= 0; length:= 0;
  621. WHILE i # numOfWords DO
  622. quadlet:= SYSTEM.VAL(SET,SYSTEM.GET32(bufAddr+length));
  623. (* FirewireLowUtil.PrintSet(quadlet); *)
  624. quadletSwap:= LSH(quadlet*{0..7},24);
  625. quadletSwap:= quadletSwap+LSH(quadlet*{8..15},8);
  626. quadletSwap:= quadletSwap+LSH(quadlet*{16..23},-8);
  627. quadletSwap:= quadletSwap+LSH(quadlet*{24..31},-24);
  628. (* FirewireLowUtil.PrintSet(quadletSwap); *)
  629. SYSTEM.PUT32(bufAddr+length,SYSTEM.VAL(LONGINT,quadletSwap));
  630. INC(i); INC(length,4);
  631. END;
  632. END InvertByteOrder;
  633. (* Allocates quadlet aligned buffers *)
  634. PROCEDURE AllocBuf(size:LONGINT;VAR ptrToBfr: Buffer):SET;
  635. VAR buffer: Buffer; adr: ADDRESS; s: SET;
  636. BEGIN
  637. NEW(buffer, size + 4);
  638. adr:= ADDRESSOF(buffer[0]);
  639. ASSERT(adr > 0);
  640. (* Find a 4 byte aligned address *)
  641. DEC(adr, adr MOD 4);
  642. INC(adr, 4);
  643. ASSERT(adr > 0);
  644. s:= SYSTEM.VAL(SET,adr);
  645. ptrToBfr:= buffer;
  646. RETURN s;
  647. END AllocBuf;
  648. PROCEDURE Probe*;
  649. VAR i,j,k: LONGINT; node: FirewireLowUtil.Node; ud: FirewireLowUtil.UnitDirectory;
  650. BEGIN
  651. i:= 0; j:= 0; k:= 0;
  652. (* Print(debug,"<<<<<<<<<<<<<<<<<<<<<<<<<< SBP2 >>>>>>>>>>>>>>>>>>>>>>>>>>"); *)
  653. host:= FirewireLow.c.OHCI;
  654. WHILE FirewireLow.c.OHCI.Nodes[i] # NIL DO
  655. node:= FirewireLow.c.OHCI.Nodes[i];
  656. WHILE node.uds[j] # NIL DO
  657. ud:= node.uds[j];
  658. IF ud.hasLogicalUnitDir THEN
  659. WHILE ud.luns[k] # NIL DO
  660. ScanUD(node,i,ud.luns[k],ud,TRUE); INC(k);
  661. END
  662. ELSE ScanUD(node,i,ud,ud,FALSE)
  663. END;
  664. INC(j)
  665. END;
  666. INC(i)
  667. END;
  668. numOfGrps:= i-1;
  669. (* Print(debug,"Leaving Probe!"); *)
  670. END Probe;
  671. PROCEDURE ConvertSpeedToPayload(speed: LONGINT):LONGINT;
  672. BEGIN
  673. CASE speed OF
  674. 0: RETURN 7H (* 512 *);
  675. |1: RETURN 8H (* 1024 *);
  676. |2: RETURN 9H (* 2048 *);
  677. |3: RETURN 0AH (* 4096 *);
  678. |4: RETURN 0BH (* 8192 *);
  679. |5: RETURN 0CH (* 16384 *);
  680. END;
  681. END ConvertSpeedToPayload;
  682. PROCEDURE ConvertPayloadToMaxRec(payload: LONGINT):LONGINT;
  683. BEGIN
  684. payload:= payload-20;
  685. IF payload = 4 THEN RETURN 1H
  686. ELSIF payload = 8 THEN RETURN 2H
  687. ELSIF payload = 16 THEN RETURN 3H
  688. ELSIF payload = 32 THEN RETURN 4H
  689. ELSIF payload = 64 THEN RETURN 5H
  690. ELSIF payload = 128 THEN RETURN 6H
  691. ELSIF payload = 256 THEN RETURN 7H
  692. ELSIF payload = 512 THEN RETURN 8H
  693. ELSIF payload = 1024 THEN RETURN 9H
  694. ELSIF payload = 2048 THEN RETURN 0AH
  695. ELSIF payload = 4096 THEN RETURN 0BH
  696. ELSIF payload = 8192 THEN RETURN 0CH
  697. ELSIF payload = 16384 THEN RETURN 0DH
  698. ELSIF payload = 32768 THEN RETURN 0EH
  699. ELSIF payload = 65536 THEN RETURN 0FH
  700. ELSE RETURN 0H
  701. END
  702. END ConvertPayloadToMaxRec;
  703. PROCEDURE CreateCommandOrbPool(dev: Sbp2Dev);
  704. (* does nothing *)
  705. END CreateCommandOrbPool;
  706. PROCEDURE Sbp2LogoutDevice(VAR dev: Sbp2Dev): BOOLEAN;
  707. VAR buffer: ARRAY 2 OF SET; i,addr: LONGINT; t: Kernel.Timer;
  708. BEGIN
  709. NEW(t);
  710. (* Print(debug,"Logging out of the device"); *)
  711. dev.logoutOrb.reserved1:= 0;
  712. dev.logoutOrb.reserved2:= 0;
  713. dev.logoutOrb.reserved3:= 0;
  714. dev.logoutOrb.reserved4:= 0;
  715. (* set the logout function *)
  716. dev.logoutOrb.loginIDMisc:= {};
  717. dev.logoutOrb.loginIDMisc:= (* SYSTEM.VAL(SET,LSH(7,16)); *) {16,17,18};
  718. (* set the login id *)
  719. (* Print(debug,"Printing the login id: "); FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,dev.loginResp.bufAddr)))*{0..15});
  720. dev.logoutOrb.loginIDMisc:=
  721. dev.logoutOrb.loginIDMisc + SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,dev.loginResp.bufAddr)))*{0..15};
  722. (* set the notify bit *) *)
  723. dev.logoutOrb.loginIDMisc:= dev.logoutOrb.loginIDMisc + {31};
  724. dev.logoutOrb.reserved5:= 0;
  725. dev.logoutOrb.statusFIFOLo:= dev.statusBlock.bufAddr;
  726. (* Print(debug,"Printing the status buffer address");
  727. FirewireLowUtil.PrintSet(dev.statusBlock.bufAddr); *)
  728. dev.logoutOrb.statusFIFOHi:= LSH(FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{0..15},16);
  729. (* now write the structure into the buffers *)
  730. (* Print(debug,"Printing the logoutOrb buffer address"); *)
  731. addr:= SYSTEM.VAL(LONGINT,dev.logoutOrb.bufAddr);
  732. (* FirewireLowUtil.PrintSet(dev.logoutOrb.bufAddr); *)
  733. SYSTEM.PUT32(addr,dev.logoutOrb.reserved1);
  734. SYSTEM.PUT32(addr+4,dev.logoutOrb.reserved2);
  735. SYSTEM.PUT32(addr+8,dev.logoutOrb.reserved3);
  736. SYSTEM.PUT32(addr+12,dev.logoutOrb.reserved4);
  737. SYSTEM.PUT32(addr+16,dev.logoutOrb.loginIDMisc);
  738. SYSTEM.PUT32(addr+20,dev.logoutOrb.reserved5);
  739. SYSTEM.PUT32(addr+24,{});
  740. SYSTEM.PUT32(addr+28,dev.logoutOrb.statusFIFOLo);
  741. (* byte swap the content *)
  742. InvertByteOrder(addr,32);
  743. (* let's write to the target's management agent register *)
  744. buffer[0]:= LSH(FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{0..15},16);
  745. buffer[1]:= dev.logoutOrb.bufAddr;
  746. (* Print(debug,"Address before byte swapping");
  747. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,buffer[0]));
  748. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,buffer[1])); *)
  749. (* swap bytes *)
  750. InvertByteOrderWord(buffer[1]);
  751. (* Print(debug,"Address after byte swapping");
  752. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,buffer[0]));
  753. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,buffer[1])); *)
  754. (* Print(debug,"Writing to node!"); *)
  755. (* Print(debug,"Printing the management agent address!");
  756. FirewireLowUtil.PrintSet(dev.mgmtAgntAddrLow);FirewireLowUtil.PrintSet(dev.mgmtAgntAddrHigh); *)
  757. IF ~HpsbNodeWrite(dev.nodeEntry, dev.mgmtAgntAddrLow,
  758. dev.mgmtAgntAddrHigh, SYSTEM.VAL(SET,ADDRESSOF(buffer)), 8) THEN
  759. Print(debug,"Writing to the management agent failed");
  760. END;
  761. (* should wait up to 20 seconds *)
  762. t.Sleep(50);
  763. addr:= SYSTEM.VAL(LONGINT,dev.statusBlock.bufAddr);
  764. (* Print(debug,"Printing the status"); *) i:= 0;
  765. WHILE (SYSTEM.GET32(addr) = 0) & (i<10) DO t.Sleep(50); INC(i); Print(debug,"I'm waiting"); END;
  766. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr)));
  767. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+4))); *)
  768. (* make sure that address belongs to this login orb
  769. IF ~(dev.logoutOrb.bufAddr = SYSTEM.VAL(SET,SYSTEM.GET32(addr+4))) THEN
  770. Print(debug,"The status block belongs to a wrong orb"); RETURN FALSE
  771. END; *)
  772. (* check the status
  773. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  774. Print(debug,"Printing the status");
  775. FirewireLowUtil.PrintSet(statusHi);
  776. IF ({28,29}*statusHi # {}) OR (27 IN statusHi) OR ({16..23}* statusHi # {}) THEN
  777. KernelLog.String("There was an error logging out of the device!"); KernelLog.Ln();
  778. RETURN FALSE
  779. END; *)
  780. (* Print(debug,"Logout was successfull!"); *)
  781. RETURN TRUE;
  782. END Sbp2LogoutDevice;
  783. PROCEDURE Sbp2LoginDevice(VAR dev: Sbp2Dev): BOOLEAN;
  784. VAR buffer: ARRAY 2 OF SET; i,addr: LONGINT; t: Kernel.Timer; statusHi: SET;
  785. BEGIN
  786. NEW(t);
  787. (* Print(debug,"Logging into device"); *)
  788. (* initialize login orb, no password *)
  789. dev.loginOrb.passwordHi:= 0;
  790. dev.loginOrb.passwordLo:= 0;
  791. dev.loginOrb.loginRespHi:= 0; (* LSH(SYSTEM.VAL(LONGINT,LSH(FirewireLowUtil.GetBusID(),6)) + host.nodeID,16); *)
  792. dev.loginOrb.loginRespLo:= SYSTEM.VAL(LONGINT,dev.loginResp.bufAddr);
  793. dev.loginOrb.lunMisc:= (* SYSTEM.VAL(SET,LSH(LoginRequest,16)) + *)
  794. LSH({},20) (* one second reconnect time *) +
  795. LSH({0},28) (* exclusive login *) +
  796. LSH({0},31) (* notify us when the login is complete *);
  797. (* now set the lun if initialized *)
  798. IF SYSTEM.VAL(LONGINT,dev.logicalUnitNumber) # UninitializedLUN THEN
  799. dev.loginOrb.lunMisc:= dev.loginOrb.lunMisc + SYSTEM.VAL(SET,dev.logicalUnitNumber);
  800. (* KernelLog.Int(SYSTEM.VAL(LONGINT,dev.logicalUnitNumber),2); KernelLog.Ln(); *)
  801. ELSE Print(debug,"LUN uninitialized");
  802. END;
  803. dev.loginOrb.passwrdRespLens:= 16;
  804. dev.loginOrb.statusFIFOLo:= dev.statusBlock.bufAddr;
  805. (* Print(debug,"Printing the status buffer address");
  806. FirewireLowUtil.PrintSet(dev.statusBlock.bufAddr); *)
  807. dev.loginOrb.statusFIFOHi:= LSH(FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{0..15},16);
  808. (* now write the structure into the buffers *)
  809. (* Print(debug,"Printing the loginOrb buffer address"); *)
  810. addr:= SYSTEM.VAL(LONGINT,dev.loginOrb.bufAddr);
  811. (* FirewireLowUtil.PrintSet(dev.loginOrb.bufAddr); *)
  812. SYSTEM.PUT32(addr,dev.loginOrb.passwordHi);
  813. SYSTEM.PUT32(addr+4,dev.loginOrb.passwordLo);
  814. SYSTEM.PUT32(addr+8,{});
  815. SYSTEM.PUT32(addr+12,dev.loginOrb.loginRespLo);
  816. SYSTEM.PUT32(addr+16,dev.loginOrb.lunMisc);
  817. SYSTEM.PUT32(addr+20,dev.loginOrb.passwrdRespLens);
  818. SYSTEM.PUT32(addr+24,{});
  819. SYSTEM.PUT32(addr+28,dev.loginOrb.statusFIFOLo);
  820. (* byte swap the content *)
  821. InvertByteOrder(addr,32);
  822. (* let's write to the target's management agent register *)
  823. buffer[0]:= {};
  824. buffer[1]:= dev.loginOrb.bufAddr; (*
  825. Print(debug,"Address before byte swapping");
  826. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,buffer[0]));
  827. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,buffer[1])); *)
  828. (* swap bytes *)
  829. InvertByteOrderWord(buffer[1]); (*
  830. Print(debug,"Address after byte swapping");
  831. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,buffer[0]));
  832. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,buffer[1])); *)
  833. dev.loginComplete:= FALSE;
  834. (* Print(debug,"Writing to node!"); *)
  835. (* Print(debug,"Printing the management agent address!");
  836. FirewireLowUtil.PrintSet(dev.mgmtAgntAddrLow);FirewireLowUtil.PrintSet(dev.mgmtAgntAddrHigh); *)
  837. IF ~HpsbNodeWrite(dev.nodeEntry, dev.mgmtAgntAddrLow,
  838. dev.mgmtAgntAddrHigh, SYSTEM.VAL(SET,ADDRESSOF(buffer)), 8) THEN
  839. Print(debug,"Writing to the management agent failed");
  840. END;
  841. (* should wait up to 20 seconds *)
  842. t.Sleep(50);
  843. addr:= SYSTEM.VAL(LONGINT,dev.statusBlock.bufAddr);
  844. (* Print(debug,"Printing the status"); *) i:= 0;
  845. WHILE (SYSTEM.GET32(addr) = 0) & (i<10) DO t.Sleep(50); INC(i); Print(debug,"I'm waiting"); END;
  846. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr)));
  847. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+4))); *)
  848. (* make sure that address belongs to this login orb *)
  849. IF ~(dev.loginOrb.bufAddr = SYSTEM.VAL(SET,SYSTEM.GET32(addr+4))) THEN
  850. Print(debug,"The status block belongs to a wrong orb"); RETURN FALSE
  851. END;
  852. (* check the status *)
  853. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  854. IF ({28,29}*statusHi # {}) OR (27 IN statusHi) OR ({16..23}* statusHi # {}) THEN
  855. KernelLog.String("There was an error logging into the device!"); KernelLog.Ln();
  856. FirewireLowUtil.PrintSet(statusHi);
  857. RETURN FALSE
  858. END;
  859. (* take the command block agent address *)
  860. (* Print(debug,"Printing the command block agent address"); *)
  861. addr:= SYSTEM.VAL(LONGINT,dev.loginResp.bufAddr);
  862. (* Print(debug,"Printing the login id: "); FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr))*{0..15}); *)
  863. dev.cmdBlckAgntAddrHigh:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
  864. (* FirewireLowUtil.PrintSet(dev.cmdBlckAgntAddrHigh); *)
  865. dev.cmdBlckAgntAddrLow:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
  866. (* FirewireLowUtil.PrintSet(dev.cmdBlckAgntAddrLow); *)
  867. KernelLog.String("Successfully logged into 1394 device"); KernelLog.Ln();
  868. RETURN TRUE;
  869. END Sbp2LoginDevice;
  870. PROCEDURE HpsbNodeWrite(ne: FirewireLowUtil.Node; addrLow, addrHigh: SET;buffer: SET; len: LONGINT):BOOLEAN;
  871. VAR generation,i: LONGINT; result: BOOLEAN;
  872. BEGIN
  873. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,bufAddr))));
  874. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,bufAddr)+4))); *)
  875. generation:= FirewireLowUtil.GetGeneration();
  876. i:= 0;
  877. WHILE (i<4) & ~result DO
  878. IF FirewireLow.c.Write1394(host.ATController.GetReqContest(),host,ne.phyID,generation, buffer, addrLow,addrHigh,len) THEN
  879. (* Print(debug,"Write was successfull!"); *) result:= TRUE;
  880. ELSE Print(debug,"Write was not successfull!"); result:= FALSE;
  881. END;
  882. INC(i);
  883. END;
  884. RETURN result
  885. END HpsbNodeWrite;
  886. PROCEDURE StartDev(VAR dev: Sbp2Dev);
  887. BEGIN
  888. (* Print(debug,"Starting device!"); *)
  889. dev.loginResp.bufAddr:= AllocBuf(16,dev.loginResp.ptrToBfr); (* 4 quadlets *)
  890. dev.queryLogins.bufAddr:= AllocBuf(32,dev.queryLogins.ptrToBfr); (* 8 quadlets *)
  891. dev.queryLoginsResp.bufAddr:= AllocBuf(16,dev.queryLoginsResp.ptrToBfr);
  892. dev.reconnectOrb.bufAddr:= AllocBuf(32,dev.reconnectOrb.ptrToBfr);
  893. dev.logoutOrb.bufAddr:= AllocBuf(32,dev.logoutOrb.ptrToBfr);
  894. dev.loginOrb.bufAddr:= AllocBuf(32,dev.loginOrb.ptrToBfr);
  895. dev.statusBlock.bufAddr:= AllocBuf(32,dev.statusBlock.ptrToBfr);
  896. CreateCommandOrbPool(dev);
  897. IF ~Sbp2LoginDevice(dev) THEN KernelLog.String("Login into device failed"); KernelLog.Ln(); RETURN END;
  898. (* Set max retries to a large number *)
  899. SetBusyTimeOut(dev.nodeEntry);
  900. (* do a fetch agent reset *)
  901. AgentReset(dev);
  902. (* get the max speed and packet size we can use *)
  903. MaxSpeedAndSize(dev);
  904. dev.Config();
  905. END StartDev;
  906. (** Scans the unit directory *)
  907. PROCEDURE ScanUD(node: FirewireLowUtil.Node;index: LONGINT; ud, udPar: FirewireLowUtil.UnitDirectory; isLUN: BOOLEAN);
  908. VAR devGrp: SbpDevGrp; i: LONGINT; dev: Sbp2Dev; devNum,lunNum: ARRAY 10 OF CHAR;
  909. name: Plugins.Name;
  910. BEGIN
  911. ParseUD(devGrp,ud,udPar,isLUN);
  912. sbpDevGrps[index]:= devGrp;
  913. i:= 0;
  914. WHILE devGrp[i] # NIL DO
  915. dev:= devGrp[i];
  916. dev.nodeEntry:= node;
  917. dev.speedCode:= 0; (* stands for 100 in 1394 *)
  918. dev.maxPayload:= ConvertSpeedToPayload(dev.speedCode);
  919. dev.loginComplete:= FALSE;
  920. StartDev(dev);
  921. devGrp[i]:= dev;
  922. Strings.IntToStr(index,devNum);
  923. Strings.IntToStr(i,lunNum);
  924. name := "1394Dev";
  925. Strings.Append(name,devNum);
  926. Strings.Append(name,lunNum);
  927. dev.SetName(name);
  928. AddStorageDevices(dev);
  929. (* Print(debug,"Storing device on index: "); KernelLog.Int(i,2); KernelLog.Ln();
  930. KernelLog.Int(dev.maxPayload,2); KernelLog.Ln(); *)
  931. INC(i);
  932. END;
  933. sbpDevGrps[index]:= devGrp;
  934. END ScanUD;
  935. PROCEDURE AddStorageDevices(VAR dev: Sbp2Dev);
  936. VAR res: WORD;
  937. BEGIN
  938. (* now add to disk system *)
  939. Disks.registry.Add(dev,res);
  940. IF res#Plugins.Ok THEN
  941. KernelLog.Ln;
  942. KernelLog.String("AosFireWireStorage: Error: Couldn't add device to Disks.registry (Error code: ");
  943. KernelLog.Int(res,0); KernelLog.String(")"); KernelLog.Ln;
  944. RETURN;
  945. END;
  946. END AddStorageDevices;
  947. PROCEDURE RemoveStorageDevice(VAR dev: Sbp2Dev);
  948. BEGIN
  949. IF ~Sbp2LogoutDevice(dev) THEN KernelLog.String("Device could not be removed!") END;
  950. Disks.registry.Remove(dev);
  951. END RemoveStorageDevice;
  952. PROCEDURE RemoveAllStorageDevices;
  953. VAR index,index2,numOfDev: LONGINT; grp: SbpDevGrp; dev: Sbp2Dev;
  954. BEGIN
  955. index:= 0; index2:= 0;
  956. numOfDev:= numOfGrps;
  957. WHILE index <= numOfDev DO
  958. grp:= sbpDevGrps[index];
  959. WHILE grp[index2] # NIL DO
  960. dev:= grp[index2];
  961. RemoveStorageDevice(dev);
  962. INC(index2);
  963. END;
  964. IF index2 = 1 THEN DEC(numOfDev) END;
  965. INC(index);
  966. END;
  967. END RemoveAllStorageDevices;
  968. PROCEDURE ParseUD(VAR grp: SbpDevGrp; ud,udPar: FirewireLowUtil.UnitDirectory; isLUN: BOOLEAN);
  969. VAR mgmtAgntAddrLow, mgmtAgntAddrHigh, unitChar: SET; commandSetSpecID, commandSet, firmwareRev: LONGINT;
  970. i,j,length,key,value: LONGINT; dev: Sbp2Dev;
  971. BEGIN
  972. (* Print(debug,"Parsing unit directory!"); *)
  973. length:= ud.GetLength(); i:= 0;
  974. WHILE i < (length) DO
  975. key:= SYSTEM.VAL(LONGINT,LSH(ud.udEntries[i],-24));
  976. value:= SYSTEM.VAL(LONGINT,ud.udEntries[i]*{0..23});
  977. CASE key OF
  978. SBP2CSROffsetKey: mgmtAgntAddrLow:= FirewireLowUtil.CSRBaseLow;
  979. mgmtAgntAddrHigh:= FirewireLowUtil.CSRBaseHigh;
  980. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,value)); *)
  981. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,LSH(value,2)));
  982. FirewireLowUtil.PrintSet(mgmtAgntAddrLow); *)
  983. mgmtAgntAddrLow:= SYSTEM.VAL(SET,LSH(value,2)) + mgmtAgntAddrLow;
  984. (* Print(debug,"Found management agent address"); *)
  985. (* FirewireLowUtil.PrintSet(mgmtAgntAddrLow); *)
  986. |SBP2CommandSetSpecIDKey: commandSetSpecID:= value;
  987. |SBP2CommandSetKey: commandSet:= value;
  988. |SBP2UnitCharKey: unitChar:= SYSTEM.VAL(SET,value);
  989. |SBP2DeviceTypeAndLUNKey: NEW(dev); (* KernelLog.Int(value,2); KernelLog.Ln(); *) dev.logicalUnitNumber:= SYSTEM.VAL(SET,value)*{0..15}; j:= 0;
  990. (* FirewireLowUtil.PrintSet(dev.logicalUnitNumber); *)
  991. WHILE (grp[j] # NIL) DO
  992. INC(j);
  993. END;
  994. ASSERT(j < 64); grp[j]:= dev; (* add this device to the grp *)
  995. (* Print(debug,"Found a logical unit number"); *)
  996. |SBP2FirmwareRevKey: firmwareRev:= value;
  997. ELSE
  998. END;
  999. INC(i);
  1000. END;
  1001. IF isLUN THEN (* scan parent to get common values *) ParseUD(grp,udPar,udPar,FALSE);
  1002. ELSE
  1003. IF ~(grp[0] # NIL) THEN (* the list is empty so we will add a defult base id *)
  1004. NEW(dev); dev.logicalUnitNumber:= SYSTEM.VAL(SET,UninitializedLUN); grp[0]:= dev;
  1005. (* Print(debug,"There was no logical unit number, initialize with default id"); *)
  1006. END;
  1007. (* update all generic data *)
  1008. (* Print(debug,"Updating generic data"); *)
  1009. i:= 0;
  1010. WHILE grp[i] # NIL DO
  1011. dev:= grp[i];
  1012. (* Print(debug,"Writing the management agent address"); *)
  1013. dev.mgmtAgntAddrLow:= mgmtAgntAddrLow;
  1014. dev.mgmtAgntAddrHigh:= mgmtAgntAddrHigh;
  1015. dev.commandSetSpecID:= commandSetSpecID;
  1016. dev.commandSet:= commandSet;
  1017. dev.unitChar:= unitChar;
  1018. dev.firmwareRev:= firmwareRev;
  1019. grp[i]:= dev;
  1020. INC(i);
  1021. END
  1022. END;
  1023. END ParseUD;
  1024. PROCEDURE Print(debug: BOOLEAN; string: ARRAY OF CHAR);
  1025. BEGIN
  1026. IF debug THEN KernelLog.String(string); KernelLog.Ln() END;
  1027. END Print;
  1028. (** Test procedure *)
  1029. PROCEDURE TestTransfer*;
  1030. VAR diskres,ofs,i: LONGINT; data: ARRAY 1024 OF CHAR; dev: Sbp2Dev;grp: SbpDevGrp;
  1031. tempSet: SET;
  1032. BEGIN
  1033. ofs:= 0;
  1034. grp:= sbpDevGrps[0];
  1035. dev:= grp[0];
  1036. (* dev.GetSize(size,diskres); *)
  1037. FOR i:= 0 TO 3 DO
  1038. data[i]:= SYSTEM.VAL(CHAR,{});
  1039. END;
  1040. Print(debug,"Reading from medium");
  1041. dev.Transfer(Disks.Read,900,2,data,ofs,diskres); tempSet:= {};
  1042. FOR i:= 0 TO 3 DO
  1043. tempSet:= tempSet + LSH(SYSTEM.VAL(SET,data[i]),-(i*8));
  1044. END;
  1045. FirewireLowUtil.PrintSet(tempSet);
  1046. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(data))));
  1047. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(data)+512)));
  1048. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(data)+1024))); *)
  1049. FOR i:= 0 TO 3 DO
  1050. data[i]:= SYSTEM.VAL(CHAR,{0});
  1051. END;
  1052. (* SYSTEM.PUT32(ADDRESSOF(data),SYSTEM.VAL(LONGINT,{0,3,6,9,12,15,18,21,24,27,30}));
  1053. SYSTEM.PUT32(ADDRESSOF(data)+512,SYSTEM.VAL(LONGINT,{1,11}));
  1054. SYSTEM.PUT32(ADDRESSOF(data)+1024,SYSTEM.VAL(LONGINT,{1,2,3,4,5})); *)
  1055. Print(debug,"Writing to medium");
  1056. dev.Transfer(Disks.Write,900,2,data,ofs,diskres);
  1057. FOR i:= 0 TO 3 DO
  1058. data[i]:= SYSTEM.VAL(CHAR,{});
  1059. END;
  1060. Print(debug,"Reading from medium");
  1061. dev.Transfer(Disks.Read,900,2,data,ofs,diskres);
  1062. FOR i:= 0 TO 3 DO
  1063. tempSet:= tempSet + LSH(SYSTEM.VAL(SET,data[i]),-(i*8));
  1064. END;
  1065. FirewireLowUtil.PrintSet(tempSet);
  1066. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(data))));
  1067. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(data)+512)));
  1068. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(data)+1024))); *)
  1069. END TestTransfer;
  1070. (* PROCEDURE TestHandle*(par:ANY):ANY;
  1071. VAR msg: Disks.GetGeometryMsg; diskres: LONGINT; dev: Sbp2Dev;grp: SbpDevGrp;
  1072. BEGIN
  1073. grp:= sbpDevGrps[0];
  1074. dev:= grp[0];
  1075. dev.Handle(msg,diskres);
  1076. RETURN NIL
  1077. END TestHandle; *)
  1078. (*
  1079. PROCEDURE Transfer*(op,block,num: LONGINT; VAR data: ARRAY OF CHAR; ofs: LONGINT; VAR diskres: LONGINT);
  1080. VAR i,addr: LONGINT; command: Command; dev: Sbp2Dev; grp: SbpDevGrp; statusHi: SET;
  1081. BEGIN
  1082. grp:= sbpDevGrps[0];
  1083. dev:= grp[0];
  1084. command.bufferAddr:= SYSTEM.VAL(SET,ADDRESSOF(data));
  1085. command.bufferLen:= blockSize;
  1086. FOR i:= 0 TO 11 DO command.cdb[i]:= CHR(0) END;
  1087. IF (op = Disks.Read) OR (op = Disks.Write) THEN
  1088. IF op = Disks.Read THEN
  1089. command.cdb[0]:= 28X; command.dataDirection:= DataRead
  1090. ELSE
  1091. command.cdb[0]:= 2AX; command.dataDirection:= DataWrite
  1092. END;
  1093. i:= 0;
  1094. WHILE num > 0 DO
  1095. command.bufferAddr:= SYSTEM.VAL(SET,ADDRESSOF(data)+i*blockSize);
  1096. command.cdb[2]:= CHR(LSH(block,-24));
  1097. command.cdb[3]:= CHR(LSH(block,-16));
  1098. command.cdb[4]:= CHR(LSH(block,-8));
  1099. command.cdb[5]:= CHR(block);
  1100. command.cdb[7]:= CHR(LSH(num,-8));
  1101. command.cdb[8]:= CHR(num);
  1102. IF ~SendCommand(dev, command, diskres) THEN RETURN END;
  1103. IF diskres # Disks.Ok THEN RETURN END;
  1104. INC(block);DEC(num);INC(i);
  1105. END
  1106. ELSE
  1107. diskres:= Disks.Unsupported;
  1108. END;
  1109. grp[0]:= dev;
  1110. sbpDevGrps[0]:= grp;
  1111. (* SYSTEM.PUT32(ADDRESSOF(data),SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)));
  1112. (* check the status *)
  1113. addr:= SYSTEM.VAL(LONGINT,dev.statusBlock.bufAddr);
  1114. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  1115. WHILE statusHi = {} DO
  1116. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  1117. END;
  1118. FirewireLowUtil.PrintSet(statusHi);
  1119. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+4)));
  1120. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+8)));
  1121. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+12)));
  1122. IF ({28,29}*statusHi # {}) OR (27 IN statusHi) OR ({16..23}* statusHi # {}) THEN
  1123. KernelLog.String("There was an error sending the command!"); KernelLog.Ln();
  1124. ELSE Print(debug,"There was no error sending the command!");
  1125. END; *)
  1126. (*
  1127. IF op = Disks.Read THEN
  1128. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)))); *)
  1129. SYSTEM.PUT32(ADDRESSOF(data),SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)));
  1130. InvertByteOrder(ADDRESSOF(data),4);
  1131. END; *)
  1132. END Transfer;
  1133. PROCEDURE GetSize*(VAR size: LONGINT;diskres: LONGINT);
  1134. VAR command: Command; data : ARRAY 8 OF CHAR; i: LONGINT; dev: Sbp2Dev; grp: SbpDevGrp;
  1135. BEGIN
  1136. grp:= sbpDevGrps[0];
  1137. dev:= grp[0];
  1138. (* blockSize := 0; size := 0; *)
  1139. command.bufferAddr:= AllocBuf(1024);
  1140. (* FirewireLowUtil.PrintSet(dev.mgmtAgntAddrLow);
  1141. KernelLog.Int(dev.maxPayload,2); KernelLog.Ln(); *)
  1142. (* command.bufferAddr:= SYSTEM.VAL(SET,ADDRESSOF(data)); *)
  1143. command.bufferLen:= 1024;
  1144. command.dataDirection:= DataRead;
  1145. (* UFI: Read Capacity command *)
  1146. FOR i:= 0 TO 11 DO command.cdb[i] := CHR(0); END;
  1147. command.cdb[0] := 25X;
  1148. IF ~SendCommand(dev,command,diskres) THEN END;
  1149. IF (diskres # Disks.Ok) THEN RETURN; END;
  1150. (* data[0]:= CHR(2);
  1151. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(data)))); *)
  1152. (* FOR i := 0 TO 3 DO
  1153. size := size*100H + SYSTEM.GET8(SYSTEM.VAL(LONGINT,command.bufferAddr)+i);
  1154. blockSize := blockSize*100H + SYSTEM.GET8(SYSTEM.VAL(LONGINT,command.bufferAddr)+4+i);
  1155. END; *)
  1156. size:= SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr));
  1157. blockSize:= SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)+4);
  1158. INC (size);
  1159. diskres := Disks.Ok;
  1160. KernelLog.String("UsbStorage: Disk info: Blocks: "); KernelLog.Int(size, 0);
  1161. KernelLog.String(" blocksize: "); KernelLog.Int(blockSize,0);
  1162. KernelLog.String(" size: "); KernelLog.Int(size*blockSize,0);
  1163. KernelLog.String(" size in giga: "); KernelLog.Int(((size DIV 1024)*(blockSize)) DIV (1024*1024),0);
  1164. KernelLog.Ln;
  1165. grp[0]:= dev;
  1166. sbpDevGrps[0]:= grp;
  1167. END GetSize;
  1168. PROCEDURE TestSendCommand*(par:ANY):ANY;
  1169. VAR buffer,bufferAnsw: ARRAY 1024 OF CHAR; command: Command; grp: SbpDevGrp; dev: Sbp2Dev; statusHi: SET;
  1170. addr,i,diskres,size: LONGINT;
  1171. BEGIN
  1172. (* check size
  1173. Print(debug,"Checking the size");
  1174. GetSize(size,diskres);
  1175. KernelLog.Int(diskres,2); *)
  1176. grp:= sbpDevGrps[0];
  1177. dev:= grp[0];
  1178. (* FirewireLowUtil.PrintSet(dev.mgmtAgntAddrLow);
  1179. KernelLog.Int(dev.maxPayload,2); KernelLog.Ln(); *)
  1180. Print(debug,"Writing to medium");
  1181. command.bufferLen:= 1024;
  1182. command.bufferAddr:= SYSTEM.VAL(SET,ADDRESSOF(buffer));
  1183. SYSTEM.PUT32(SYSTEM.VAL(LONGINT,command.bufferAddr),SYSTEM.VAL(LONGINT,{0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30}));
  1184. command.dataDirection:= DataWrite;
  1185. FOR i:= 0 TO 2 DO
  1186. SYSTEM.PUT32(ADDRESSOF(command.cdb)+i*4,0);
  1187. END;
  1188. command.cdb[0]:= 2AX; (* write *)
  1189. command.cdb[1]:= CHR(SYSTEM.VAL(LONGINT,{5}));
  1190. command.cdb[2]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH(SYSTEM.VAL(SET,260),-24)));
  1191. command.cdb[3]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH(SYSTEM.VAL(SET,260),-16)));
  1192. command.cdb[4]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH(SYSTEM.VAL(SET,260),-8)));
  1193. command.cdb[5]:= CHR(SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,260)*{0..7}));
  1194. command.cdb[7]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH({6},-8)));
  1195. command.cdb[8]:= CHR(SYSTEM.VAL(LONGINT,{6}*{0..7}));
  1196. IF ~SendCommand(dev, command,diskres) THEN Print(debug,"Send command failed") END;
  1197. (* check the status *)
  1198. addr:= SYSTEM.VAL(LONGINT,dev.statusBlock.bufAddr);
  1199. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  1200. WHILE statusHi = {} DO
  1201. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  1202. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)))); *)
  1203. END;
  1204. FirewireLowUtil.PrintSet(statusHi);
  1205. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+4)));
  1206. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+8)));
  1207. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+12)));
  1208. IF ({28,29}*statusHi # {}) OR (27 IN statusHi) OR ({16..23}* statusHi # {}) THEN
  1209. KernelLog.String("There was an error sending the command!"); KernelLog.Ln();
  1210. ELSE Print(debug,"There was no error sending the command!");
  1211. END;
  1212. Print(debug,"Reading from medium");
  1213. command.bufferLen:= 1024;
  1214. command.bufferAddr:= SYSTEM.VAL(SET,ADDRESSOF(bufferAnsw));
  1215. (* SYSTEM.PUT32(command.bufferAddr,SYSTEM.VAL(LONGINT,{0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30})); *)
  1216. command.dataDirection:= DataRead;
  1217. FOR i:= 0 TO 2 DO
  1218. SYSTEM.PUT32(ADDRESSOF(command.cdb)+i*4,0);
  1219. END;
  1220. command.cdb[0]:= 28X; (* read *)
  1221. command.cdb[1]:= CHR(SYSTEM.VAL(LONGINT,{5}));
  1222. command.cdb[2]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH(SYSTEM.VAL(SET,245),-24)));
  1223. command.cdb[3]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH(SYSTEM.VAL(SET,245),-16)));
  1224. command.cdb[4]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH(SYSTEM.VAL(SET,245),-8)));
  1225. command.cdb[5]:= CHR(SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,245)*{0..7}));
  1226. command.cdb[7]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH({5},-8)));
  1227. command.cdb[8]:= CHR(SYSTEM.VAL(LONGINT,{5}*{0..7}));
  1228. IF ~SendCommand(dev, command,diskres) THEN Print(debug,"Send command failed") END;
  1229. (* check the status *)
  1230. addr:= SYSTEM.VAL(LONGINT,dev.statusBlock.bufAddr);
  1231. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  1232. WHILE statusHi = {} DO
  1233. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  1234. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)))); *)
  1235. END;
  1236. FirewireLowUtil.PrintSet(statusHi);
  1237. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+4)));
  1238. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+8)));
  1239. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+12)));
  1240. IF ({28,29}*statusHi # {}) OR (27 IN statusHi) OR ({16..23}* statusHi # {}) THEN
  1241. KernelLog.String("There was an error sending the command!"); KernelLog.Ln();
  1242. ELSE Print(debug,"There was no error sending the command!");
  1243. END;
  1244. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr))));
  1245. Print(debug,"Reading from medium");
  1246. command.bufferLen:= 1024;
  1247. command.bufferAddr:= SYSTEM.VAL(SET,ADDRESSOF(bufferAnsw));
  1248. (* SYSTEM.PUT32(command.bufferAddr,SYSTEM.VAL(LONGINT,{0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30})); *)
  1249. command.dataDirection:= DataRead;
  1250. FOR i:= 0 TO 2 DO
  1251. SYSTEM.PUT32(ADDRESSOF(command.cdb)+i*4,0);
  1252. END;
  1253. command.cdb[0]:= 28X; (* read *)
  1254. command.cdb[1]:= CHR(SYSTEM.VAL(LONGINT,{5}));
  1255. command.cdb[2]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH(SYSTEM.VAL(SET,260),-24)));
  1256. command.cdb[3]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH(SYSTEM.VAL(SET,260),-16)));
  1257. command.cdb[4]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH(SYSTEM.VAL(SET,260),-8)));
  1258. command.cdb[5]:= CHR(SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,260)*{0..7}));
  1259. command.cdb[7]:= CHR(SYSTEM.VAL(LONGINT,{0..7}*LSH({5},-8)));
  1260. command.cdb[8]:= CHR(SYSTEM.VAL(LONGINT,{5}*{0..7}));
  1261. IF ~SendCommand(dev, command,diskres) THEN Print(debug,"Send command failed") END;
  1262. (* check the status *)
  1263. addr:= SYSTEM.VAL(LONGINT,dev.statusBlock.bufAddr);
  1264. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  1265. WHILE statusHi = {} DO
  1266. statusHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr));
  1267. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr)))); *)
  1268. END;
  1269. FirewireLowUtil.PrintSet(statusHi);
  1270. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+4)));
  1271. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+8)));
  1272. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(addr+12)));
  1273. IF ({28,29}*statusHi # {}) OR (27 IN statusHi) OR ({16..23}* statusHi # {}) THEN
  1274. KernelLog.String("There was an error sending the command!"); KernelLog.Ln();
  1275. ELSE Print(debug,"There was no error sending the command!");
  1276. END;
  1277. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,command.bufferAddr))));
  1278. RETURN NIL;
  1279. END TestSendCommand;
  1280. *)
  1281. PROCEDURE Cleanup;
  1282. BEGIN
  1283. RemoveAllStorageDevices();
  1284. (* Print(debug,"All storage devices removed"); *)
  1285. END Cleanup;
  1286. BEGIN
  1287. debug:= TRUE;
  1288. Modules.InstallTermHandler(Cleanup);
  1289. END FirewireSBP2.