FirewireLow.Mod 112 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632
  1. MODULE FirewireLow; (** AUTHOR "VIP"; PURPOSE "IEEE 1394 Generic Driver"; *)
  2. IMPORT SYSTEM, KernelLog, Machine, PCI, Objects, Modules, FirewireLowUtil, Kernel, Strings;
  3. CONST
  4. MaxSelfIDErrors= 16;
  5. busNumber= {6..15};
  6. LinkEnable = 17;
  7. LPS = 19;
  8. masterIntEnable = 31;
  9. reqTxComplete = 0;
  10. respTxComplete = 1;
  11. ARRQ = 2;
  12. ARRS = 3;
  13. RQPkt = 4;
  14. RSPkt = 5;
  15. isochTx = 6;
  16. isochRx = 7;
  17. postedWriteErr = 8;
  18. lockRespErr = 9;
  19. selfIDComplete2 = 15;
  20. selfIDComplete = 16;
  21. busReset = 17;
  22. regAccessFail = 18;
  23. phy = 19;
  24. cycleSynch = 20;
  25. cycle64Seconds = 21;
  26. cycleLost = 22;
  27. cycleInconsistent = 23;
  28. unrecoverableError = 24;
  29. cycleTooLong = 25;
  30. phyRegRcvd = 26;
  31. ackTardy = 27;
  32. softInterrupt = 29;
  33. rcvSelfID = 9;
  34. TYPE
  35. OHCIPacket = FirewireLowUtil.OHCIPacket;
  36. Contest = FirewireLowUtil.Contest;
  37. ListMember= FirewireLowUtil.ListMember;
  38. Controller= OBJECT
  39. VAR
  40. base,irq:LONGINT; OHCI*: FirewireLowUtil.OHCIDesc; t: Kernel.Timer; timer: Kernel.MilliTimer;
  41. timeout: BOOLEAN; clock: Objects.Timer;
  42. (** Is used to handle an await timeout *)
  43. PROCEDURE HandleTimeout;
  44. VAR ms: LONGINT;
  45. BEGIN {EXCLUSIVE}
  46. ms:= Kernel.Left(timer);
  47. IF ms <= 0 THEN
  48. timeout := TRUE;
  49. ELSE
  50. (* KernelLog.Enter; KernelLog.String("Timer early "); KernelLog.Int(ms, 1); KernelLog.Exit; *)
  51. Objects.SetTimeout(clock, SELF.HandleTimeout, ms)
  52. END
  53. END HandleTimeout;
  54. (** Allocates the receive buffer for the SelfID DMA context *)
  55. PROCEDURE SelfIDAlloc;
  56. VAR buffer: FirewireLowUtil.CharBuffer; adr: ADDRESS; s: SET;
  57. BEGIN
  58. (* KernelLog.String("Entering ConfigSelfID"); *)
  59. KernelLog.Ln();
  60. (* Allocating 10K buffer , although I just need 8192 *)
  61. NEW(buffer,10240);
  62. (* find a 2K aligned address *)
  63. adr := ADDRESSOF(buffer[0]);
  64. DEC(adr,adr MOD 2048);
  65. INC(adr,2048);
  66. s := SYSTEM.VAL(SET,adr);
  67. (* setting the buffer address *)
  68. OHCI.SelfIDBufferAdr:= s;
  69. OHCI.ptrToSelfIDBuf:= buffer;
  70. (* Setting the max selfid retries *)
  71. OHCI.SelfIDErrors:= 0;
  72. (* KernelLog.String("Printing the buffer address"); KernelLog.Ln();
  73. FirewireLowUtil.PrintSet(s);
  74. KernelLog.String("Leaving ConfigSelfID"); *)
  75. KernelLog.Ln();
  76. END SelfIDAlloc;
  77. (** Reads a quadlet and returns the content as a set *)
  78. PROCEDURE ReadSetQuadlet(address:LONGINT):SET;
  79. BEGIN
  80. RETURN SYSTEM.VAL(SET, SYSTEM.GET32(address));
  81. END ReadSetQuadlet;
  82. (** Checks the selfID packet stream: checks if the generation counter corresponds to the actual one and also checks the integrity of the packets *)
  83. PROCEDURE CheckSelfIDStream():BOOLEAN;
  84. CONST offsetSize = 2; selfIDError= 31; selfIDSizeMask = {0..8};
  85. VAR selfIDSize, address, reg: SET; size: LONGINT; error: BOOLEAN;
  86. BEGIN
  87. (* KernelLog.String("Entering CheckSelfIDStream"); KernelLog.Ln(); *)
  88. error:= FALSE;
  89. address := OHCI.SelfIDBufferAdr;
  90. reg := FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount);
  91. (* Mask the size field *)
  92. selfIDSize := LSH(reg,-2);
  93. selfIDSize := selfIDSize*selfIDSizeMask;
  94. size := ConvertToLongint(selfIDSize);
  95. (* KernelLog.String("There are "); KernelLog.Int(size,2); KernelLog.String(" quadlets in the self id buffer."); KernelLog.Ln(); *)
  96. (* compare the selfIDGeneration field of the whole stream if there are errors do a bus reset *)
  97. IF CompareSelfIDGen(address,size) OR (selfIDError IN reg) THEN error:= TRUE;
  98. IF OHCI.SelfIDErrors < MaxSelfIDErrors THEN INC(OHCI.SelfIDErrors);
  99. KernelLog.String("There was an error checking the self id stream"); KernelLog.Ln();
  100. ELSE KernelLog.String("Too much errors in self id process, giving up"); KernelLog.Ln();
  101. END
  102. END;
  103. IF ~error THEN
  104. (* Reset selfID error counter *)
  105. OHCI.SelfIDErrors:= 0;
  106. (* Now Check the integrity *)
  107. IF CheckIntegrity(address,size) THEN error:= TRUE;
  108. KernelLog.String("There was an error checking the integrity of the self id stream"); KernelLog.Ln()
  109. END
  110. END;
  111. (* KernelLog.String("Leaving CheckSelfIDStream"); KernelLog.Ln(); *)
  112. RETURN error
  113. END CheckSelfIDStream;
  114. (** Prints the content of a buffer as a set *)
  115. PROCEDURE PrintBuffer(address: SET; size: LONGINT);
  116. VAR i, j, adr: LONGINT;
  117. BEGIN
  118. i:= 0;
  119. j:= 0;
  120. adr:= ConvertToLongint(address);
  121. WHILE i < size DO FirewireLowUtil.PrintSet(SYSTEM.VAL(SET, SYSTEM.GET32(adr+j)));
  122. INC(j,4); INC(i);
  123. END
  124. END PrintBuffer;
  125. (** Checks the integrity of selfID packets *)
  126. PROCEDURE CheckIntegrity(address: SET; size:LONGINT):BOOLEAN;
  127. VAR i: LONGINT;data, invData : SET; error: BOOLEAN; j: LONGINT;
  128. BEGIN
  129. (* KernelLog.String("Entering CheckIntegrity"); KernelLog.Ln(); *)
  130. error:= FALSE;
  131. j := 4; (* First bit holds status information, do not check *)
  132. i := 1;
  133. (* PrintBuffer(address,size); *)
  134. WHILE i < size DO
  135. data := SYSTEM.VAL(SET, SYSTEM.GET32(ConvertToLongint(address)+j)); INC(j,4);
  136. invData:= SYSTEM.VAL(SET, SYSTEM.GET32(ConvertToLongint(address)+j));
  137. IF ~(({0..31}-data) = invData) THEN
  138. KernelLog.String("Integrity is broken"); KernelLog.Ln(); error:= TRUE; i:= size;
  139. ELSE (* KernelLog.String("Integrity check was successfull"); KernelLog.Ln() *)
  140. END;
  141. INC(j,4);
  142. INC(i,2);
  143. END;
  144. (* KernelLog.String("Leaving CheckIntegrity"); KernelLog.Ln(); *)
  145. RETURN error
  146. END CheckIntegrity;
  147. (** Compares the generation field of selfID packets with the generation counter of the system to see if they correspond *)
  148. PROCEDURE CompareSelfIDGen(address:SET; size:LONGINT):BOOLEAN;
  149. CONST selfIDGenMask = {16..23}; offsetGen = 16;
  150. VAR header, selfIDGeneration: SET; i: LONGINT; error: BOOLEAN;
  151. BEGIN
  152. (* KernelLog.String("Entering Procedure CompareSelfIDGen"); KernelLog.Ln(); *)
  153. (* Read the header of the first SelfID packet *)
  154. error:= FALSE;
  155. header := SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(address)));
  156. (* Mask the selfIDGeneration field *)
  157. selfIDGeneration := header*selfIDGenMask;
  158. (* check if selfIDGen field is the same as in selfIDCountRegister *)
  159. i:= 0;
  160. header := ReadSetQuadlet(ConvertToLongint(address));
  161. header := header*selfIDGenMask;
  162. IF ~(header = selfIDGeneration) THEN
  163. KernelLog.String("selfIDGeneration mismatch");KernelLog.Ln(); error:= TRUE
  164. END;
  165. (* KernelLog.String("Leaving compare SelfIDGen "); KernelLog.Ln(); *)
  166. RETURN error;
  167. END CompareSelfIDGen;
  168. (** Converts a SET to a LONGINT *)
  169. PROCEDURE ConvertToLongint(reg: SET):LONGINT;
  170. BEGIN
  171. RETURN SYSTEM.VAL(LONGINT,reg);
  172. END ConvertToLongint;
  173. (** Processes sent packets *)
  174. PROCEDURE ProcSentPckts(contest: Contest) ;
  175. VAR packet: OHCIPacket; status: SET; ack,dataSize: LONGINT; block: FirewireLowUtil.Block;
  176. CONST acks= 4; code= {0..4};
  177. BEGIN
  178. (* KernelLog.String("Processing sent packets!"); KernelLog.Ln(); *)
  179. WHILE ~contest.listInserted.GetPacket(packet) DO
  180. dataSize:= packet.dataSize;
  181. block:= packet.block;
  182. IF (dataSize > 0) & (packet.type # FirewireLowUtil.raw) THEN
  183. status:= LSH(SYSTEM.VAL(SET, SYSTEM.GET32(block.end + 12)),-16)
  184. ELSE status:= LSH(SYSTEM.VAL(SET, SYSTEM.GET32(block.start + 12)),-16)
  185. END;
  186. (* KernelLog.String("Printing the status: "); FirewireLowUtil.PrintSet(status); KernelLog.Ln(); *)
  187. (* check if it's an ack *)
  188. IF (acks IN status) THEN ack:= SYSTEM.VAL(LONGINT,status*code);
  189. (* KernelLog.String("It's an ack!"); KernelLog.Ln(); *)
  190. ELSE (* it's an event code *)
  191. KernelLog.String("It's an event code!"); KernelLog.Ln();
  192. CASE (ConvertToLongint(status*code)) OF
  193. FirewireLowUtil.EvtNoStatus: KernelLog.String("No event status!"); KernelLog.Ln()
  194. | FirewireLowUtil.EvtLongPacket: ack:= FirewireLowUtil.AckError;
  195. KernelLog.String("The received data length was greater than the buffer's data length!");KernelLog.Ln()
  196. | FirewireLowUtil.EvtMissingAck: ack:= FirewireLowUtil.AckError;
  197. KernelLog.String("A subaction gap was detected before an ack arrived or the received ack had a parity error!");
  198. KernelLog.Ln()
  199. | FirewireLowUtil.EvtUnderrun: ack:= FirewireLowUtil.AckError;
  200. KernelLog.String("Underrun on the corresponding FIFO. The packet was truncated!"); KernelLog.Ln()
  201. | FirewireLowUtil.EvtOverrun: ack:= FirewireLowUtil.AckError;
  202. KernelLog.String("A receive FIFO overflowed during the reception of an isochronous packet!"); KernelLog.Ln()
  203. | FirewireLowUtil.EvtDescriptorRead: ack:= FirewireLowUtil.AckError;
  204. KernelLog.String("An unrecoverable error occurred while the Host Controller was reading a descriptor block!");
  205. KernelLog.Ln()
  206. | FirewireLowUtil.EvtDataRead: ack:= FirewireLowUtil.AckError;
  207. KernelLog.String("An error occurred while the Host Controller was attempting to"); KernelLog.Ln();
  208. KernelLog.String(" read from host memory in the data stage of descriptor processing!"); KernelLog.Ln();
  209. | FirewireLowUtil.EvtDataWrite: ack:= FirewireLowUtil.AckError;
  210. KernelLog.String("An error occurred while the Host Controller was attempting to "); KernelLog.Ln();
  211. KernelLog.String("write to host memory in the data stage of descriptor processing "); KernelLog.Ln();
  212. KernelLog.String("or when processing a single 16-bit host memory write!"); KernelLog.Ln()
  213. | FirewireLowUtil.EvtBusReset: ack:= FirewireLowUtil.AckError;
  214. KernelLog.String("This is the synthesized bus reset packet!"); KernelLog.Ln();
  215. | FirewireLowUtil.EvtTimeout: ack:= FirewireLowUtil.AckError;
  216. KernelLog.String("This asynchronous transmit response packet expired and"); KernelLog.Ln();
  217. KernelLog.String(" was not transmitted or an IT DMA context experienced "); KernelLog.Ln();
  218. KernelLog.String("a skip processing overflow!"); KernelLog.Ln();
  219. | FirewireLowUtil.EvtTcodeErr: ack:= FirewireLowUtil.AckError;
  220. KernelLog.String("This packet has a bad event code!"); KernelLog.Ln()
  221. | FirewireLowUtil.EvtUnknown: ack:= FirewireLowUtil.AckError;
  222. KernelLog.String("Unknown error condition!"); KernelLog.Ln();
  223. | FirewireLowUtil.EvtFlushed: ack:= FirewireLowUtil.AckError;
  224. KernelLog.String("This packet was flushed due to a bus reset!"); KernelLog.Ln();
  225. ELSE KernelLog.String("Unhandled or reserved event!"); KernelLog.Ln()
  226. END;
  227. RETURN
  228. END;
  229. PacketSent(contest,packet,FirewireLowUtil.ConvertToSet(ack));
  230. (* This should never happen, is already checked by while *)
  231. ASSERT(~contest.listInserted.DelPacket(packet));
  232. END;
  233. IF FillFifo(contest) THEN
  234. KernelLog.String("There was an error in FIllFifo"); KernelLog.Ln()
  235. END;
  236. (* KernelLog.String("Leaving process sent packets!"); KernelLog.Ln(); *)
  237. END ProcSentPckts;
  238. (** Processes dma receive buffers *)
  239. PROCEDURE ProcRcvdPckts(context: Contest);
  240. VAR block: FirewireLowUtil.Block; i, bufSize, packetSize, resCount,packetBytesLeft, packetBytesRight: LONGINT;
  241. bufferAddr, tCode,ack: SET; packetAddr,nextDesc: LONGINT; complete: BOOLEAN;
  242. BEGIN
  243. (* KernelLog.String("Entering ProcRcvdPckts"); KernelLog.Ln(); *)
  244. bufSize:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc)))*{0..15});
  245. resCount:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 12))*{0..15});
  246. packetSize:= FirewireLowUtil.PacketLength(context);
  247. bufferAddr:= SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 4));
  248. packetAddr:= ConvertToLongint(bufferAddr) + context.prgr.packetOffset;
  249. tCode:= SYSTEM.VAL(SET,LSH(SYSTEM.GET32(packetAddr),-4)) * {0..3};
  250. ASSERT(packetAddr > 0);
  251. (* dump packet
  252. i:=0;
  253. KernelLog.String("Dumping packet:"); KernelLog.Ln();
  254. WHILE i< packetSize DO
  255. quad:= SYSTEM.VAL(SET,SYSTEM.GET32(packetAddr +i));
  256. FirewireLowUtil.PrintSet(quad); INC(i,4);
  257. END; *)
  258. IF packetSize < 4 THEN (* Something is wrong, there must be an error *)
  259. KernelLog.String("The packet size is wrong::procRcvdPckts"); KernelLog.Ln();
  260. FirewireLowUtil.StopContext(context.ctrlClear);
  261. RETURN
  262. END;
  263. (* The first case handles packets that cross more than one buffer *)
  264. IF (context.prgr.packetOffset + packetSize) > bufSize THEN
  265. (* KernelLog.String("First case!"); KernelLog.Ln(); *)
  266. (* reassemble split packet in a new buffer and free the last one *)
  267. packetBytesLeft:= bufSize - context.prgr.packetOffset; i:= 0;
  268. ASSERT(packetBytesLeft <= FirewireLowUtil.BufSize);
  269. WHILE i < packetBytesLeft-1 DO
  270. SYSTEM.PUT32(ConvertToLongint(context.tempBuffer[0])+i,SYSTEM.GET32(packetAddr + i));
  271. INC(i,4)
  272. END;
  273. (* free this descriptor and its buffer to be reused *)
  274. block.end:= ConvertToLongint(context.prgr.curDesc);
  275. (* now go to next buffer/descriptor *)
  276. nextDesc:= SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 8)-1; (* -1 to eliminate the z *)
  277. ASSERT(nextDesc > 0);
  278. bufSize:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(nextDesc))*{0..15});
  279. resCount:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(nextDesc + 12))*{0..15});
  280. packetBytesRight:= bufSize - resCount; i:= 0;
  281. ASSERT(packetAddr > 0);
  282. ASSERT(packetBytesRight <= FirewireLowUtil.BufSize-packetBytesLeft);
  283. WHILE i < packetBytesRight-1 DO
  284. SYSTEM.PUT32(ConvertToLongint(context.tempBuffer[0])+packetBytesLeft+i,SYSTEM.GET32(packetAddr + i));
  285. INC(i,4)
  286. END;
  287. context.prgr.curDesc:= SYSTEM.VAL(SET,nextDesc);
  288. ASSERT(ConvertToLongint(context.prgr.curDesc) > 0);
  289. block.start:= ConvertToLongint(context.prgr.curDesc);
  290. context.prgr.packetOffset:= bufSize-resCount;
  291. (* ok, we finished copying the packet into a safe place *)
  292. ELSE (* The packet is all in one buffer *)
  293. (* KernelLog.String("Second case"); KernelLog.Ln(); *)
  294. packetBytesLeft:= bufSize - context.prgr.packetOffset; i:= 0;
  295. ASSERT(packetBytesLeft <= FirewireLowUtil.BufSize);
  296. WHILE i < packetBytesLeft-1 DO
  297. SYSTEM.PUT32(ConvertToLongint(context.tempBuffer[0])+i,SYSTEM.GET32(packetAddr + i));
  298. INC(i,4)
  299. END;
  300. IF resCount = 0 THEN
  301. (* free this descriptor and its buffer to be reused *)
  302. block.end:= ConvertToLongint(context.prgr.curDesc);
  303. nextDesc:= SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 8)-1;
  304. context.prgr.curDesc:= SYSTEM.VAL(SET,nextDesc);
  305. ASSERT(ConvertToLongint(context.prgr.curDesc) > 0);
  306. block.start:= ConvertToLongint(context.prgr.curDesc);
  307. END;
  308. context.prgr.packetOffset:= bufSize-resCount;
  309. END;
  310. IF (SYSTEM.VAL(LONGINT,tCode) = FirewireLowUtil.PhyARReq) THEN
  311. (* We always get this packet after bus reset, just throw it away *)
  312. (* i:=0;
  313. KernelLog.String("Dumping packet:"); KernelLog.Ln();
  314. WHILE i< packetSize DO
  315. quad:= SYSTEM.VAL(SET,SYSTEM.GET32(packetAddr +i));
  316. IF i= 12 THEN quad:= quad*{8..31}; KernelLog.Int(SYSTEM.VAL(LONGINT,LSH(quad,-8)),2);
  317. KernelLog.Ln()
  318. END;
  319. FirewireLowUtil.PrintSet(quad); INC(i,4);
  320. END;
  321. KernelLog.String("Discarding phy packet::ProcRcvdPckts"); KernelLog.Ln(); *)
  322. ELSE
  323. (* find out if we got an ack complete acknowledgement *)
  324. ack:= FirewireLowUtil.ReadReg(context.ctrlSet) * {0..4};
  325. IF ConvertToLongint(ack) = FirewireLowUtil.AckComplete THEN complete:= TRUE
  326. ELSE complete:= FALSE
  327. END;
  328. (* dump packet
  329. i:=0;
  330. KernelLog.String("Dumping packet:"); KernelLog.Ln();
  331. WHILE i< packetSize DO
  332. quad:= SYSTEM.VAL(SET,SYSTEM.GET32(packetAddr +i));
  333. IF i= 12 THEN quad:= quad*{8..31}; KernelLog.Int(SYSTEM.VAL(LONGINT,LSH(quad,-8)),2);
  334. KernelLog.Ln()
  335. END;
  336. FirewireLowUtil.PrintSet(quad); INC(i,4);
  337. END; *)
  338. PacketReceived(context,context.tempBuffer[0], packetSize, complete);
  339. END;
  340. (* KernelLog.String("Leaving ProcRcvdPckts"); KernelLog.Ln(); *)
  341. END ProcRcvdPckts;
  342. (** Frees unused DMA buffers of receive contexts *)
  343. PROCEDURE FreeDMABuffer(context:Contest);
  344. VAR curDesc: LONGINT; active: LONGINT;
  345. BEGIN
  346. active:= 10;
  347. curDesc:= ConvertToLongint(context.prgr.curDesc);
  348. ASSERT(ConvertToLongint(context.prgr.curDesc) > 0);
  349. context.prgr.SetBranchAddress(curDesc+1,curDesc+8,context.prgr.ptrToBuf);
  350. context.buffers.FreeBuffer(SYSTEM.VAL(SET,SYSTEM.GET32(curDesc + 4)));
  351. (* wake up the context if necessary *)
  352. IF ~(active IN FirewireLowUtil.ReadReg(context.ctrlSet)) THEN
  353. (* KernelLog.String("Waking context "); KernelLog.String(context.name); KernelLog.String("!"); KernelLog.Ln() *)
  354. END;
  355. (* Always wake it up, to avoid race conditions *)
  356. FirewireLowUtil.WriteReg(context.ctrlSet,{12});
  357. END FreeDMABuffer;
  358. (** Checks the transaction code of a received packet to see if its a response or request packet *)
  359. PROCEDURE PacketReceived(context: Contest; bufferAddr:SET; packetSize: LONGINT; complete: BOOLEAN);
  360. VAR tCode: LONGINT;
  361. BEGIN
  362. (* KernelLog.String("Entering Packet received"); KernelLog.Ln(); *)
  363. IF OHCI.inBusReset THEN KernelLog.String("Ignoring packet, because OHCI is in bus reset!"); RETURN END;
  364. (* get tCode *)
  365. tCode:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,LSH(SYSTEM.GET32(ConvertToLongint(bufferAddr)),-4))*{0..3});
  366. (* KernelLog.String("The transaction code is: ");KernelLog.Int(tCode,2); KernelLog.Ln(); *)
  367. CASE tCode OF
  368. FirewireLowUtil.NoDataWARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
  369. |FirewireLowUtil.QReadARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
  370. |FirewireLowUtil.BReadARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
  371. |FirewireLowUtil.LockARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
  372. |FirewireLowUtil.QWriteARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
  373. |FirewireLowUtil.BWriteARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
  374. |FirewireLowUtil.NoDataQRARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
  375. |FirewireLowUtil.BReadARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
  376. |FirewireLowUtil.LockARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
  377. |FirewireLowUtil.IRCode: KernelLog.String("Received iso packet: NOT YET IMPLEMENTED!");
  378. KernelLog.Ln()
  379. |FirewireLowUtil.CycleStartCode: (* Just ignore *) (* KernelLog.String("Cycle start packet ignored!");
  380. KernelLog.Ln() *)
  381. ELSE KernelLog.String("Received bad tCode for a packet!"); KernelLog.Ln()
  382. END;
  383. (* KernelLog.String("Leaving Packet received"); KernelLog.Ln(); *)
  384. END PacketReceived;
  385. (** Creates a reply packet to read or write requests *)
  386. PROCEDURE CreateReplyPacket(VAR p: FirewireLowUtil.OHCIPacket; dataAddr: LONGINT; dataSize: LONGINT);
  387. BEGIN
  388. (* KernelLog.String("Data size in CreateReaplyPacket is: "); KernelLog.Int(dataSize,2); KernelLog.Ln(); *)
  389. p:= OHCI.packetFIFO.GetPacket();
  390. p.dataSize:= dataSize;
  391. (* reset packet *)
  392. FirewireLowUtil.ResetPacket(p);
  393. p.type:= FirewireLowUtil.async;
  394. p.state:= FirewireLowUtil.UNUSED;
  395. p.host:= OHCI;
  396. p.nodeID:= SYSTEM.VAL(SET,LSH(SYSTEM.GET32(dataAddr+4),-16))*{0..5};
  397. p.tLabel:= SYSTEM.VAL(SET,LSH(SYSTEM.GET32(dataAddr),-10))*{0..5};
  398. p.generation:= FirewireLowUtil.GetGeneration();
  399. p.respExpected:= FALSE;
  400. END CreateReplyPacket;
  401. (** Writes packet data to a host memory address *)
  402. PROCEDURE WriteToAddress(dataAddr: LONGINT; dataLen: LONGINT; writeAddrLo, writeAddrHi: SET):LONGINT;
  403. VAR i: LONGINT;
  404. BEGIN
  405. (* KernelLog.String("WriteToAddress!"); KernelLog.Ln();
  406. KernelLog.String("Printing the address"); KernelLog.Ln();
  407. FirewireLowUtil.PrintSet(writeAddrLo);
  408. FirewireLowUtil.PrintSet(writeAddrHi); *)
  409. i:= 0;
  410. IF writeAddrHi*{0..15} # {} THEN
  411. RETURN FirewireLowUtil.respAddressError
  412. ELSIF ~OHCI.adrCheck.Find(ConvertToLongint(writeAddrLo)) THEN HALT(55);
  413. ELSE
  414. FOR i:= 0 TO dataLen-1 DO
  415. SYSTEM.PUT32(ConvertToLongint(writeAddrLo)+i*4,SYSTEM.GET32(dataAddr+i*4))
  416. END
  417. END;
  418. RETURN FirewireLowUtil.respComplete;
  419. END WriteToAddress;
  420. (** Reads packet data from a host memory address *)
  421. PROCEDURE ReadFromAddress(VAR bufferAddr: ARRAY OF SET; dataLen: LONGINT; readAddrLo, readAddrHi: SET): LONGINT;
  422. VAR i: LONGINT;
  423. BEGIN
  424. (* KernelLog.String("ReadFromAddress!"); KernelLog.Ln();
  425. KernelLog.String("Printing the address"); KernelLog.Ln();
  426. FirewireLowUtil.PrintSet(readAddrLo);
  427. FirewireLowUtil.PrintSet(readAddrHi); *)
  428. i:= 0;
  429. FOR i:= 0 TO dataLen-1 DO
  430. bufferAddr[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(readAddrLo)+i*4));
  431. (* FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(readAddrLo)+i*4))); *)
  432. END;
  433. RETURN FirewireLowUtil.respComplete;
  434. END ReadFromAddress;
  435. (** Handles incoming requests *)
  436. PROCEDURE HandleIncomingPacket(bufferAddr: SET; packetSize, tCode: LONGINT; complete: BOOLEAN);
  437. VAR addrHi,addrLo: SET; rCode,dataLen,addr: LONGINT; packet: FirewireLowUtil.OHCIPacket; respBufferAddr: LONGINT;
  438. respQuadlet: ARRAY 1 OF SET;
  439. BEGIN
  440. (* KernelLog.String("Entered routine HandleIcomingPacket!"); KernelLog.Ln(); *)
  441. addr:= ConvertToLongint(bufferAddr);
  442. CASE tCode OF
  443. FirewireLowUtil.QWriteARReq:
  444. (* KernelLog.String("It's a quadlet write request!"); KernelLog.Ln(); *)
  445. addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
  446. addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
  447. rCode:= WriteToAddress(addr+12,1,addrLo,addrHi);
  448. IF ~complete THEN
  449. CreateReplyPacket(packet,addr,0);
  450. FirewireLowUtil.FillAsyncWriteResp(packet,rCode);
  451. IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
  452. (* KernelLog.String("Response successfully sent"); KernelLog.Ln() *)
  453. ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
  454. END
  455. END
  456. |FirewireLowUtil.BWriteARReq:
  457. (* KernelLog.String("It's a block write request!"); KernelLog.Ln(); *)
  458. addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
  459. addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
  460. dataLen:= (LSH(SYSTEM.GET32(addr+12),-16));
  461. rCode:= WriteToAddress(addr+16,(dataLen DIV 4),addrLo,addrHi);
  462. IF ~complete THEN
  463. CreateReplyPacket(packet,addr,0);
  464. FirewireLowUtil.FillAsyncWriteResp(packet,rCode);
  465. IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
  466. (* KernelLog.String("Response successfully sent"); KernelLog.Ln() *)
  467. ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
  468. END
  469. END
  470. |FirewireLowUtil.NoDataQRARReq:
  471. (* KernelLog.String("It's a quadlet read request!"); KernelLog.Ln(); *)
  472. addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
  473. addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
  474. rCode:= ReadFromAddress(respQuadlet,1,addrLo,addrHi);
  475. CreateReplyPacket(packet,addr,0);
  476. FirewireLowUtil.FillAsyncReadQuadResp(packet,rCode,respBufferAddr);
  477. IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
  478. (* KernelLog.String("Response successfully sent"); KernelLog.Ln() *)
  479. ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
  480. END
  481. |FirewireLowUtil.BReadARReq:
  482. (* KernelLog.String("It's a block read request!"); KernelLog.Ln(); *)
  483. dataLen:= (LSH(SYSTEM.GET32(addr+12),-16));
  484. CreateReplyPacket(packet,addr,dataLen);
  485. addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
  486. addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
  487. rCode:= ReadFromAddress(packet.data^,(dataLen DIV 4),addrLo,addrHi);
  488. FirewireLowUtil.FillAsyncReadBlockResp(packet,rCode,dataLen);
  489. IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
  490. (* KernelLog.String("Response successfully sent"); KernelLog.Ln() *)
  491. ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
  492. END
  493. |FirewireLowUtil.LockARReq:
  494. ELSE KernelLog.String("This request is not supported!"); KernelLog.Ln();
  495. END;
  496. END HandleIncomingPacket;
  497. (** Handles incoming packet responses *)
  498. PROCEDURE HandlePacketResponse(respContext: Contest; bufferAddr: SET; packetSize, tCode: LONGINT);
  499. VAR oneBack,temp: POINTER TO ListMember; tLabel, nodeID: SET; found, tCodeMatch: BOOLEAN; packet: OHCIPacket;
  500. data: LONGINT; i: LONGINT; context: Contest; n: FirewireLowUtil.FIFONode;
  501. BEGIN
  502. (* KernelLog.String("Entering handle packet response!"); KernelLog.Ln(); *)
  503. context:= OHCI.ATController.GetReqContest();
  504. (* Find the request packet corresponding to this response *)
  505. found:= FALSE;
  506. oneBack:= context.listAwaiting.head;
  507. temp:= oneBack.next;
  508. nodeID:= SYSTEM.VAL(SET,LSH(SYSTEM.GET32(ConvertToLongint(bufferAddr)+4),-16))*{0..5};
  509. tLabel:= SYSTEM.VAL(SET,LSH(SYSTEM.GET32(ConvertToLongint(bufferAddr)),-10))*{0..5};
  510. (* KernelLog.String("Printing the transaction label of the response packet!"); KernelLog.Ln();
  511. FirewireLowUtil.PrintSet(tLabel); *)
  512. IF ~context.listAwaiting.GetPacket(packet) THEN
  513. (* KernelLog.String("Printing the request packet name: "); KernelLog.String(packet.name); KernelLog.Ln();
  514. KernelLog.String("Printing the request packet transaction label: "); FirewireLowUtil.PrintSet(packet.tLabel); *)
  515. ELSE
  516. KernelLog.String("We have a problem"); KernelLog.Ln()
  517. END;
  518. WHILE (temp # NIL) & ~(found) DO (*
  519. KernelLog.String("Comparing the transaction label"); KernelLog.Ln();
  520. FirewireLowUtil.PrintSet(temp.data.tLabel);
  521. FirewireLowUtil.PrintSet(tLabel);
  522. KernelLog.String("Comparing the node id"); KernelLog.Ln();
  523. FirewireLowUtil.PrintSet(temp.data.nodeID); FirewireLowUtil.PrintSet(nodeID); *)
  524. IF (temp.data.tLabel = tLabel) & (temp.data.nodeID = nodeID) THEN
  525. found:= TRUE; packet:= temp.data; (* KernelLog.String("name of the packet is: ");
  526. KernelLog.String(temp.data.name); KernelLog.Ln(); *)
  527. ELSE oneBack:= temp; temp:= temp.next
  528. END
  529. END;
  530. IF ~found THEN KernelLog.String("This packet was not expected, no tLabel match"); KernelLog.Ln();
  531. RETURN
  532. END;
  533. (*
  534. KernelLog.String("Dumping packet: "); KernelLog.Ln();
  535. KernelLog.String("The packet name is: "); KernelLog.String(packet.name); KernelLog.Ln();
  536. FOR i:= 0 TO (packet.headerSize DIV 4)-1 DO
  537. FirewireLowUtil.PrintSet(packet.header[i]);
  538. END; i:= 0;
  539. KernelLog.String("The transaction code is: "); KernelLog.Int(tCode,2); KernelLog.Ln();
  540. KernelLog.String("The packet transaction code is: "); KernelLog.Int(SYSTEM.VAL(LONGINT,packet.tCode),2); KernelLog.Ln();
  541. *)
  542. CASE SYSTEM.VAL(LONGINT,packet.tCode) OF
  543. FirewireLowUtil.QWriteATReq:
  544. IF (tCode = FirewireLowUtil.NoDataWARRes) THEN tCodeMatch:= TRUE END
  545. |FirewireLowUtil.BWriteATReq:
  546. IF (tCode = FirewireLowUtil.NoDataWARRes) THEN tCodeMatch:= TRUE END
  547. |FirewireLowUtil.BReadATReq:
  548. IF (tCode = FirewireLowUtil.BReadARRes) THEN tCodeMatch:= TRUE END
  549. |FirewireLowUtil.NoDataWATReq:
  550. IF (tCode = FirewireLowUtil.QReadARRes) THEN tCodeMatch:= TRUE END
  551. |FirewireLowUtil.LockATReq:
  552. IF (tCode = FirewireLowUtil.LockARRes) THEN tCodeMatch:= TRUE END
  553. END;
  554. IF (~tCodeMatch OR (packet.tLabel # tLabel)) OR (packet.nodeID # nodeID) THEN
  555. IF tCodeMatch THEN (* KernelLog.String("Transaction code matched!"); KernelLog.Ln() *)
  556. ELSE KernelLog.String("Transaction code didn't match: "); FirewireLowUtil.PrintSet(packet.tCode);
  557. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,tCode)); KernelLog.Ln()
  558. END;
  559. KernelLog.String("This packet was not expected, tcode mismatch!"); RETURN
  560. END;
  561. IF found THEN (* delete packet from list *)
  562. IF oneBack = temp THEN (* It's the first object in the list *)
  563. context.listAwaiting.head:= context.listAwaiting.head.next
  564. ELSE oneBack.next:= temp.next;
  565. IF context.listAwaiting.last = temp THEN
  566. context.listAwaiting.last:= oneBack END;
  567. END;
  568. temp.next:= NIL;
  569. n:= context.listAwaiting.usedList.DequeuedNode(context.listAwaiting.usedQ);
  570. n.pListMember:= temp;
  571. context.listAwaiting.list.Enqueue(context.listAwaiting.q,n);
  572. END;
  573. data:= ConvertToLongint(bufferAddr);
  574. CASE tCode OF
  575. FirewireLowUtil.NoDataWARRes:
  576. packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
  577. packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
  578. packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
  579. |FirewireLowUtil.QReadARRes:
  580. packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
  581. packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
  582. packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
  583. packet.header[3]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 12));
  584. |FirewireLowUtil.BReadARRes:
  585. packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
  586. packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
  587. packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
  588. packet.header[3]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 12));
  589. FOR i:= 0 TO ((packetSize-16) DIV 4)-1 DO
  590. packet.data[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(data+16+i*4))
  591. END
  592. |FirewireLowUtil.LockARRes:
  593. packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
  594. packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
  595. packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
  596. packet.header[3]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 12));
  597. IF packetSize-16 > 8 THEN
  598. FOR i:= 0 TO (8 DIV 4)-1 DO
  599. packet.data[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(data+16+i*4))
  600. END
  601. ELSE
  602. FOR i:= 0 TO ((packetSize-16) DIV 4)-1 DO
  603. packet.data[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(data+16+i*4));
  604. END
  605. END
  606. END;
  607. BEGIN{EXCLUSIVE}
  608. packet.state:= FirewireLowUtil.COMPLETE;
  609. END;
  610. packet.pending:= FALSE;
  611. OHCI.labeler.FreeTransLabel(packet.tLabel);
  612. (* now free buffer if needed *)
  613. IF packet.dataSize > 0 THEN
  614. (* KernelLog.String("Freeing buffer!"); KernelLog.Ln(); *)
  615. respContext.buffers.FreeBuffer(SYSTEM.VAL(SET,SYSTEM.GET32(packet.block.start+36)))
  616. END;
  617. PacketComplete(context,packet);
  618. (* KernelLog.String("Leaving handle packet response!"); KernelLog.Ln(); *)
  619. END HandlePacketResponse;
  620. (** This function is unused *)
  621. PROCEDURE PacketComplete(context: Contest; VAR packet: OHCIPacket);
  622. (* This function is basically used if a custom routine has to handle the packet
  623. else this packet will just return to the calling routine *)
  624. END PacketComplete;
  625. (** This function checks if the packet expects a response or finished and accordingly adds the packet to the
  626. response await list *)
  627. PROCEDURE PacketSent(context:Contest;VAR packet: OHCIPacket; ack: SET);
  628. BEGIN
  629. packet.ack:= ack;
  630. IF packet.respExpected & (packet.ack # {0,4}) THEN (* KernelLog.String("Packet is pending!"); KernelLog.Ln(); *)
  631. packet.pending:= TRUE; context.listAwaiting.AddPacket(packet) (* This list will be traversed in handlePacketResponse *)
  632. ELSE packet.pending:= FALSE; packet.state:= FirewireLowUtil.COMPLETE; OHCI.labeler.FreeTransLabel(packet.tLabel);
  633. (* KernelLog.String("{{{{{{{{{{{{{{{{{{{{{{{{{Packet is complete}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}"); KernelLog.Ln(); *)
  634. END;
  635. END PacketSent;
  636. (** This is the interrupt handler *)
  637. PROCEDURE HandleInterrupt;
  638. VAR status, reg, nodeID: SET; ctx,i: LONGINT; root, error: BOOLEAN;
  639. CONST dead= 11; isValid= 31; id= {0..5}; isRoot= 30;
  640. BEGIN
  641. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{31});
  642. status := FirewireLowUtil.ReadReg(FirewireLowUtil.CIntEvent);
  643. (* KernelLog.String("@@@@@@ Entering interrupt handler @@@@@@"); KernelLog.Ln(); *)
  644. IF reqTxComplete IN status THEN
  645. (* KernelLog.String("Completion of an AT DMA request OUTPUT-LAST* command"); KernelLog.Ln(); *)
  646. (* Read the status of the AT response context control register *)
  647. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATReqContCtrlSet);
  648. (* KernelLog.String("Printing the status of the AT request context control register: ");
  649. FirewireLowUtil.PrintSet(reg); *)
  650. IF (dead IN reg) THEN (* KernelLog.String("Context died"); KernelLog.Ln(); *) FirewireLowUtil.StopContext(FirewireLowUtil.ATReqContCtrlClear);
  651. ELSE ProcSentPckts(OHCI.ATController.GetReqContest()) END;
  652. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{reqTxComplete});
  653. END;
  654. IF respTxComplete IN status THEN
  655. (* KernelLog.String("Completion of an AT DMA response OUTPUT-LAST* command "); KernelLog.Ln(); *)
  656. (* Read the status of the AT response context control register *)
  657. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATResContCtrlSet);
  658. (* KernelLog.String("Printing the status of the AT response context control register: ");
  659. FirewireLowUtil.PrintSet(reg); *)
  660. IF (dead IN reg) THEN FirewireLowUtil.StopContext(FirewireLowUtil.ATResContCtrlClear);
  661. ELSE ProcSentPckts(OHCI.ATController.GetResContest()) END;
  662. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{respTxComplete});
  663. END;
  664. IF ARRQ IN status THEN
  665. (* KernelLog.String("Completion of an AR DMA Request context command descriptor "); KernelLog.Ln(); *)
  666. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{ARRQ});
  667. END;
  668. IF ARRS IN status THEN
  669. (* KernelLog.String("Completion of an AR DMA Response context command descriptor "); KernelLog.Ln(); *)
  670. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{ARRS});
  671. END;
  672. IF RQPkt IN status THEN
  673. (* KernelLog.String("A packet was sent to an asynchronous receive request context buffer "); KernelLog.Ln();
  674. KernelLog.String("*****************************************************************"); KernelLog.Ln(); *)
  675. (* Read the status of the AT response context control register *)
  676. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARReqContCtrlSet);
  677. (* KernelLog.String("Printing the status of the AR request context control register: ");
  678. FirewireLowUtil.PrintSet(reg); *)
  679. IF (dead IN reg) THEN FirewireLowUtil.StopContext(FirewireLowUtil.ARReqContCtrlClear);
  680. ELSE ProcRcvdPckts(OHCI.ARController.GetReqContest()) END;
  681. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{RQPkt});
  682. END;
  683. IF RSPkt IN status THEN
  684. (* KernelLog.String("A packet was sent to an asynchronous receive response context buffer "); KernelLog.Ln(); *)
  685. (* Read the status of the AT response context control register *)
  686. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARResContCtrlSet);
  687. (* KernelLog.String("Printing the status of the AR response context control register: ");
  688. FirewireLowUtil.PrintSet(reg); *)
  689. IF (dead IN reg) THEN (* KernelLog.String("Context died"); KernelLog.Ln(); *) FirewireLowUtil.StopContext(FirewireLowUtil.ARResContCtrlClear);
  690. ELSE ProcRcvdPckts(OHCI.ARController.GetResContest()) END;
  691. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{RSPkt});
  692. END;
  693. IF isochTx IN status THEN
  694. (* KernelLog.String("One or more isochronous Transmit contexts have generated an interrupt"); KernelLog.Ln(); *)
  695. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochXmitIntEvntSet);
  696. FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntEvntClear,reg);
  697. IsoSchedule(reg);
  698. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{isochTx});
  699. END;
  700. IF isochRx IN status THEN
  701. (* KernelLog.String("One or more isochronous Receive contexts have generated an interrupt "); KernelLog.Ln(); *)
  702. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochRecvIntEvntSet);
  703. IsoSchedule(reg);
  704. FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntEvntClear,reg);
  705. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{isochRx});
  706. END;
  707. IF postedWriteErr IN status THEN
  708. KernelLog.String("A host bus error occurred"); KernelLog.Ln();
  709. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{postedWriteErr});
  710. END;
  711. IF lockRespErr IN status THEN
  712. KernelLog.String("Host controller attempted to return a lock response without receiving an ack"); KernelLog.Ln();
  713. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{lockRespErr});
  714. END;
  715. IF busReset IN status THEN
  716. (* Masking out the interrupt *)
  717. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{busReset});
  718. IF ~OHCI.inBusReset THEN (* KernelLog.String("bus Reset Interrupt was thrown"); KernelLog.Ln(); *)
  719. OHCI.inBusReset:= TRUE;
  720. ELSE KernelLog.String("bus Reset Interrupt was thrown while already in progress"); KernelLog.Ln();
  721. END;
  722. END;
  723. IF selfIDComplete2 IN status THEN
  724. (* KernelLog.String("Secondary indication of the end of a selfID packet stream "); KernelLog.Ln(); *)
  725. (* should not be cleared *)
  726. END;
  727. IF selfIDComplete IN status THEN
  728. error:= FALSE;
  729. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{selfIDComplete});
  730. IF OHCI.inBusReset THEN
  731. (* KernelLog.String("Indication of the end of a selfID packet stream "); KernelLog.Ln(); *)
  732. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID);
  733. (* FirewireLowUtil.PrintNodeInfo(); *)
  734. IF isValid IN reg THEN
  735. (* KernelLog.String("Self id is valid, check self id buffer!"); KernelLog.Ln(); *)
  736. IF isRoot IN reg THEN root:= TRUE; OHCI.IsRoot:= TRUE END;
  737. nodeID:= reg*id;
  738. IF CheckSelfIDStream() THEN error:= TRUE END;
  739. ELSE KernelLog.String("Self id is not valid, do not check self id buffer!"); KernelLog.Ln()
  740. END;
  741. (* Clear busreset event and reenable the busreset interrupt *)
  742. (* KernelLog.String("Reenabling bus interrupt"); KernelLog.Ln(); *)
  743. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{busReset});
  744. FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{busReset});
  745. (* Accept physical requests from all nodes *)
  746. FirewireLowUtil.WriteReg(FirewireLowUtil.ARFilterHISet, {0..31});
  747. FirewireLowUtil.WriteReg(FirewireLowUtil.ARFilterLowSet, {0..31});
  748. (* Turning on physical dma reception *)
  749. FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterHiSet, {0..31});
  750. FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterLowSet, {0..31});
  751. FirewireLowUtil.WriteReg(FirewireLowUtil.PhyUpperBound, {16..31});
  752. IF OHCI.inBusReset THEN OHCI.inBusReset:= FALSE;
  753. ELSE KernelLog.String("This should not happen!"); KernelLog.Ln(); END;
  754. IF error THEN FirewireLowUtil.SetPhyControl({8},{6})
  755. ELSE (* Go on and build the maps *)
  756. OHCI.nodeID:= SYSTEM.VAL(LONGINT,FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{0..5});
  757. BuildMaps(); BEGIN {EXCLUSIVE} OHCI.selfIDComplete:= TRUE; END;
  758. END;
  759. ELSE KernelLog.String("SelfID received outside of bus reset"); KernelLog.Ln() END;
  760. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{selfIDComplete});
  761. FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{selfIDComplete});
  762. END;
  763. IF regAccessFail IN status THEN
  764. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{regAccessFail});
  765. KernelLog.String("Open HCI register access failed "); KernelLog.Ln();
  766. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{regAccessFail});
  767. FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{regAccessFail});
  768. END;
  769. IF phy IN status THEN
  770. KernelLog.String("phy requests an interrupt"); KernelLog.Ln();
  771. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{phy});
  772. END;
  773. IF cycleSynch IN status THEN
  774. (* KernelLog.String("A new isochronous cycle has started"); KernelLog.Ln(); *)
  775. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleSynch});
  776. END;
  777. IF cycle64Seconds IN status THEN
  778. (* KernelLog.String("The 7th bit of the cycle second counter has changed "); KernelLog.Ln(); *)
  779. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycle64Seconds});
  780. END;
  781. IF cycleLost IN status THEN
  782. KernelLog.String("No cyclestart packet is sent/received "); KernelLog.Ln();
  783. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleLost});
  784. END;
  785. IF cycleInconsistent IN status THEN
  786. (* Nothing has to be done, just clear the bit *)
  787. KernelLog.String("An inconsistent cycle start was received"); KernelLog.Ln();
  788. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleInconsistent});
  789. END;
  790. IF unrecoverableError IN status THEN
  791. KernelLog.String("Host controller encountered an unrecoverable error"); KernelLog.Ln();
  792. (* Asynchronous transmit request context *)
  793. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATReqContCtrlSet);
  794. IF dead IN reg THEN KernelLog.String("The asynchronous transmit request context died!"); KernelLog.Ln();
  795. KernelLog.String("With event code: "); reg:= reg*{0..4}; FirewireLowUtil.PrintSet(reg); KernelLog.Ln();
  796. KernelLog.String("The register content is: "); FirewireLowUtil.StopContext(FirewireLowUtil.ATReqContCtrlClear);
  797. FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(FirewireLowUtil.ATReqContCtrlSet)); KernelLog.Ln();
  798. END;
  799. (* Asynchronous transmit response context *)
  800. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATResContCtrlSet);
  801. IF dead IN reg THEN KernelLog.String("The asynchronous transmit response context died!"); KernelLog.Ln() END;
  802. (* Asynchronous receive request context *)
  803. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARReqContCtrlSet);
  804. IF dead IN reg THEN KernelLog.String("The asynchronous receive request context died!"); KernelLog.Ln() END;
  805. (* Asynchronous receive response context *)
  806. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARResContCtrlSet);
  807. IF dead IN reg THEN KernelLog.String("The asynchronous receive response context died!"); KernelLog.Ln() END;
  808. (* Isochronous transmit context control *)
  809. ctx:= FirewireLowUtil.GetAvailableITCont();
  810. FOR i:= 0 TO ctx-1 DO
  811. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochXmitCntCtrlSet + i*16);
  812. IF dead IN reg THEN KernelLog.String("The isochronous transmit context "); KernelLog.Int(i,2); KernelLog.String(" died!");
  813. KernelLog.Ln()
  814. END
  815. END;
  816. (* Isochronous receive context control *)
  817. ctx:= FirewireLowUtil.GetAvailableIRCont();
  818. FOR i:= 0 TO ctx-1 DO
  819. reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochRecvCntCtrlSet + i*32);
  820. IF dead IN reg THEN KernelLog.String("The isochronous receive context "); KernelLog.Int(i,2); KernelLog.String(" died!");
  821. KernelLog.Ln()
  822. END
  823. END;
  824. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{unrecoverableError});
  825. END;
  826. IF cycleTooLong IN status THEN
  827. KernelLog.String("An isochronous cycle lasted longer than the allotted time"); KernelLog.Ln();
  828. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleTooLong});
  829. END;
  830. IF ackTardy IN status THEN
  831. KernelLog.String("HCControl.ackTardyEnable is set to one and other conditions occur"); KernelLog.Ln();
  832. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{ackTardy});
  833. END;
  834. IF softInterrupt IN status THEN
  835. (* KernelLog.String("Software Interrupt"); KernelLog.Ln(); *)
  836. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{softInterrupt});
  837. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{softInterrupt});
  838. FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{softInterrupt});
  839. END;
  840. IF phyRegRcvd IN status THEN
  841. (* KernelLog.String("OHCI has received a register data byte"); KernelLog.Ln(); *)
  842. (* Masking out the interrupt *)
  843. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{phyRegRcvd});
  844. (* Clearing the interrupt *)
  845. FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{phyRegRcvd});
  846. (* Enabling the interrupt *)
  847. FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{phyRegRcvd});
  848. END;
  849. (* Enabling all interrupts *)
  850. FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{31});
  851. (* KernelLog.String("@@@@@@ Leaving interrupt handler @@@@@@"); KernelLog.Ln(); *)
  852. END HandleInterrupt;
  853. (** Builds the descriptor list to send a packet over the 1394 bus *)
  854. PROCEDURE SendPacket(contest: Contest; VAR packet : OHCIPacket; z: LONGINT);
  855. VAR cycleTimer: SET; desc,descLast: FirewireLowUtil.GeneralDesc; descOMI: FirewireLowUtil.OutputMoreImmediate;
  856. descOL: FirewireLowUtil.OutputLast; descOLI: FirewireLowUtil.OutputLastImmediate; block: FirewireLowUtil.Block;
  857. branchAddressPtr: ADDRESS; ptrToBuf: FirewireLowUtil.CharBuffer;
  858. BEGIN
  859. (* KernelLog.String("Sending packet to node: "); KernelLog.Int(SYSTEM.VAL(LONGINT,packet.nodeID),2); KernelLog.Ln(); *)
  860. desc.address := {};
  861. desc.branchAddress := {};
  862. IF contest.type = FirewireLowUtil.RES THEN
  863. (* KernelLog.String("Setting the timeout::SendPacket"); KernelLog.Ln(); *)
  864. (* I choose the maximum time out value: 3 sec *)
  865. cycleTimer:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochCycleTimer);
  866. desc.status:= LSH(cycleTimer*{12..24},-12) +
  867. FirewireLowUtil.ConvertToSet(LSH(LSH(ConvertToLongint(cycleTimer),-25)+3,13));
  868. ELSE desc.status:= {};
  869. END;
  870. IF (packet.type = FirewireLowUtil.async) OR (packet.type = FirewireLowUtil.raw) THEN
  871. descOMI:= FirewireLowUtil.GetAOMIDesc();
  872. descOL:= FirewireLowUtil.GetAOLDesc();
  873. descOLI:= FirewireLowUtil.GetAOLIDesc();
  874. (* KernelLog.String("Packet type is asynchronous or raw::SendPacket"); KernelLog.Ln(); *)
  875. IF packet.type = FirewireLowUtil.raw THEN
  876. (* KernelLog.String("Packet type is raw"); KernelLog.Ln(); *)
  877. desc.data[0]:= FirewireLowUtil.ConvertToSet(LSH(FirewireLowUtil.PhyATReq,4));
  878. desc.data[1]:= packet.header[0];
  879. desc.data[2]:= packet.header[1];
  880. ELSE (* KernelLog.String("Packet type is asynchronous"); KernelLog.Ln(); *)
  881. desc.data[0]:= LSH(packet.speed,16) + {23} +
  882. packet.header[0]*{0..15}; (* mask the first 16 bit of a packet header *)
  883. IF SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.StreamATReq THEN
  884. (* KernelLog.String("Sending an asynchronous stream packet"); KernelLog.Ln(); *)
  885. (* Sending an asynchronous stream packet *)
  886. desc.data[1]:= packet.header[0] * {16..31}; desc.data[0]:= desc.data[0] - {23}
  887. ELSE (* sending a normal async packet: request or response *)
  888. (* KernelLog.String("Sending a normal asynchronous packet"); KernelLog.Ln(); *)
  889. desc.data[1]:= packet.header[1] * {0..15} + packet.header[0] * {16..31};
  890. desc.data[2]:= packet.header[2]; desc.data[3]:= packet.header[3]
  891. END;
  892. END;
  893. IF packet.dataSize > 0 THEN (* block or stream transmit *)
  894. (* KernelLog.String("DataSize is bigger than zero: this is a block or stream transmit"); KernelLog.Ln(); *)
  895. IF SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.StreamATReq THEN
  896. (* KernelLog.String("It's a stream packet!"); KernelLog.Ln(); *)
  897. desc.control:= descOMI.key + {3}; (* two header quadlets for stream packets *)
  898. ELSE (* 4 header quadlets for block packets *)
  899. (* KernelLog.String("It's a block packet"); KernelLog.Ln(); *)
  900. desc.control:= descOMI.key + {4}
  901. END;
  902. descLast.control:= descOL.cmd + descOL.i + descOL.b +
  903. FirewireLowUtil.ConvertToSet(packet.dataSize);
  904. (* check if packet buffer crosses page boundaries *)
  905. (* KernelLog.String("Checking if packet crosses page size"); KernelLog.Ln(); *)
  906. ASSERT(packet.dataSize < FirewireLowUtil.BufSize);
  907. descLast.address:= FirewireLowUtil.AllocPacket(packet.data^,packet.dataSize,ADDRESSOF(OHCI.tempBuffer[0]));
  908. descLast.branchAddress:= {}; descLast.status:= {};
  909. ELSE (* quadlet or no data trasmit *)
  910. (* KernelLog.String("This is a quadlet or no data transmit, dataSize is zero"); KernelLog.Ln(); *)
  911. IF packet.type = FirewireLowUtil.raw THEN (* quadlet transmit *)
  912. (* KernelLog.String("This is quadlet transmit"); KernelLog.Ln(); *)
  913. desc.control:= descOLI.cmd + descOLI.key + descOLI.b + descOLI.i +
  914. FirewireLowUtil.ConvertToSet(packet.headerSize + 4)
  915. ELSE (* no data transmit *)
  916. (* KernelLog.String("This is a no data transmit"); KernelLog.Ln(); *)
  917. desc.control:= descOLI.cmd + descOLI.key + descOLI.b + descOLI.i +
  918. FirewireLowUtil.ConvertToSet(packet.headerSize)
  919. END
  920. END
  921. ELSE (* iso packet *)
  922. descOMI:= FirewireLowUtil.GetIOMIDesc();
  923. descOL:= FirewireLowUtil.GetIOLDesc();
  924. KernelLog.String("We have an iso packet"); KernelLog.Ln();
  925. desc.data[0]:= packet.header[0]*{0..15} +
  926. LSH(packet.speed,16);
  927. desc.data[1]:= packet.header[0]*{16..31};
  928. desc.control:= descOMI.key + {3};
  929. descLast.control:= descOL.cmd + descOL.b + descOL.i +
  930. FirewireLowUtil.ConvertToSet(packet.dataSize);
  931. descLast.address:= FirewireLowUtil.AllocPacket(packet.data^,packet.dataSize,ADDRESSOF(OHCI.tempBuffer[0]));
  932. descLast.branchAddress:= {}; descLast.status:= {};
  933. END;
  934. (* write descriptor block in program buffer *)
  935. (* KernelLog.String("Writing descriptor block in program buffer!"); KernelLog.Ln(); *)
  936. block.start:= packet.blockBufferAddr;
  937. (* KernelLog.String("Printing the block.start address!");
  938. KernelLog.Int(block.start,2); KernelLog.Ln(); *) ASSERT(block.start > 0);
  939. (* KernelLog.String("Putting first quadlet at address: "); *)(* KernelLog.Int(block.start,2); *) (* KernelLog.Ln(); *)
  940. SYSTEM.PUT32(block.start, desc.control); (* FirewireLowUtil.PrintSet(desc.control); *)
  941. SYSTEM.PUT32(block.start + 4, desc.address); (* FirewireLowUtil.PrintSet(desc.address); *)
  942. (* KernelLog.String("Putting second quadlet at address: "); KernelLog.Ln(); *)
  943. SYSTEM.PUT32(block.start + 8, desc.branchAddress); (* FirewireLowUtil.PrintSet(desc.branchAddress); *)
  944. SYSTEM.PUT32(block.start + 12, desc.status); (* FirewireLowUtil.PrintSet(desc.status); *)
  945. (* KernelLog.String("Putting third quadlet at address: "); KernelLog.Ln(); *)
  946. SYSTEM.PUT32(block.start + 16, desc.data[0]); (* FirewireLowUtil.PrintSet(desc.data[0]); *)
  947. SYSTEM.PUT32(block.start + 20, desc.data[1]); (* FirewireLowUtil.PrintSet(desc.data[1]); *)
  948. (* KernelLog.String("Putting forth quadlet at address: "); KernelLog.Ln(); *)
  949. SYSTEM.PUT32(block.start + 24, desc.data[2]); (* FirewireLowUtil.PrintSet(desc.data[2]); *)
  950. SYSTEM.PUT32(block.start + 28, desc.data[3]); (* FirewireLowUtil.PrintSet(desc.data[3]); *)
  951. IF packet.dataSize > 0 THEN
  952. (* KernelLog.String("DataSize is bigger than zero");KernelLog.Ln(); *)
  953. SYSTEM.PUT32(block.start + 32, descLast.control); (* FirewireLowUtil.PrintSet(descLast.control); *)
  954. SYSTEM.PUT32(block.start + 36, descLast.address); (* FirewireLowUtil.PrintSet(descLast.address); *)
  955. SYSTEM.PUT32(block.start + 40, descLast.branchAddress); (* FirewireLowUtil.PrintSet(descLast.branchAddress); *)
  956. SYSTEM.PUT32(block.start + 44, descLast.status); (* FirewireLowUtil.PrintSet(descLast.status); *)
  957. (* Dump data in buffer *)
  958. (* KernelLog.String("Dumping the data in buffer::SendPacket"); KernelLog.Ln();
  959. i:= 0;
  960. WHILE i< (packet.dataSize-1) DO
  961. FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,SYSTEM.GET32(SYSTEM.VAL(LONGINT,descLast.address)+i)));INC(i,4);
  962. END; *)
  963. branchAddressPtr:= block.start + 40; block.end:= block.start + 32;
  964. ptrToBuf:= packet.ptrToBlckBufAddr;
  965. ELSE
  966. branchAddressPtr:= block.start + 8; block.end:= block.start; (* This block is just one desc long *)
  967. ptrToBuf:= packet.ptrToBlckBufAddr;
  968. END;
  969. contest.prgr.SetBranchAddress(block.start+z,branchAddressPtr,ptrToBuf);
  970. packet.block:= block;
  971. contest.listInserted.AddPacket(packet);
  972. END SendPacket;
  973. (** This procedure checks the packet type to find out which context to use,
  974. builds the program and fills the FIFO. IF the packet awaits a response, It will wait until the response comes *)
  975. PROCEDURE OHCISend(VAR packet: OHCIPacket):BOOLEAN;
  976. VAR contest: FirewireLowUtil.Contest; result: BOOLEAN; i,ms: LONGINT;
  977. BEGIN
  978. IF packet.dataSize > OHCI.MaxPacketSize THEN KernelLog.String("The packet size is too big!"); KernelLog.Ln();
  979. RETURN FALSE;
  980. END;
  981. (* Find out what kind of packet we have *)
  982. IF packet.type = FirewireLowUtil.raw THEN contest:= OHCI.ATController.GetReqContest()
  983. ELSIF SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.ITCode THEN OHCI.ITController.ResetIterator();
  984. contest:= OHCI.ITController.GetNextContest() (* there are min 4 contests! *)
  985. ELSIF ((SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.NoDataWATRes) OR (SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.QReadATRes)
  986. OR (SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.BReadATRes) OR (SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.LockATRes))
  987. THEN contest:= OHCI.ATController.GetResContest()
  988. ELSE contest:= OHCI.ATController.GetReqContest()
  989. END;
  990. (* Add packet to the contest pending list *)
  991. contest.listPending.AddPacket(packet);
  992. (* KernelLog.String("Printing the content of the control set register in OHCISend:");
  993. FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(contest.ctrlSet)); KernelLog.Ln(); *)
  994. (* Fills the fifo with pending packets *)
  995. IF ~FillFifo(contest) THEN result:= TRUE ELSE result:= FALSE END;
  996. (* if packet awaits a response, wait until the response comes *)
  997. i:= 0;
  998. IF packet.respExpected THEN
  999. BEGIN{EXCLUSIVE}
  1000. ms:= 5;
  1001. Kernel.SetTimer(timer,ms);
  1002. Objects.SetTimeout(clock, SELF.HandleTimeout, ms);
  1003. timeout:= FALSE;
  1004. AWAIT((packet.state = FirewireLowUtil.COMPLETE) OR timeout)
  1005. END;
  1006. END;
  1007. IF packet.state = FirewireLowUtil.COMPLETE THEN
  1008. (* KernelLog.String("Packet received answer and is complete::ohciSend"); KernelLog.Ln() *)
  1009. ELSE (* KernelLog.String("Time out::ohciSend"); KernelLog.Ln(); *)
  1010. END;
  1011. RETURN result
  1012. END OHCISend;
  1013. (** Fills the FIFO with the context program *)
  1014. PROCEDURE FillFifo(contest: FirewireLowUtil.Contest):BOOLEAN;
  1015. VAR packet: OHCIPacket; error: BOOLEAN; z: LONGINT; tempAddr: LONGINT;
  1016. CONST isRunning= 15; active= 10;
  1017. BEGIN
  1018. (* KernelLog.String("Entering FillFifo"); KernelLog.Ln(); *)
  1019. error:= contest.listPending.GetPacket(packet);
  1020. IF (error) THEN
  1021. (* KernelLog.String("There are no more packets to send"); KernelLog.Ln(); *) RETURN FALSE
  1022. END;
  1023. (* find out if packet has data *)
  1024. (* KernelLog.String("Finding out packet data size!"); KernelLog.Ln(); *)
  1025. IF packet.dataSize > 0 THEN
  1026. z:= 3 (* use one outputMoreImmediateDescriptor and one outputLast descriptor *)
  1027. ELSE z:= 2 (* use one outputLastImmediate decriptor *)
  1028. END;
  1029. (* Insert the packet into the fifo *)
  1030. WHILE ~error DO
  1031. error:= contest.listPending.DelPacket(packet);
  1032. SendPacket(contest,packet,z);
  1033. error:= contest.listPending.GetPacket(packet);
  1034. END;
  1035. error:= FALSE;
  1036. (* IF contest.prgr.GetFreeBlocks() = 0 THEN KernelLog.String("Fifo for context "); KernelLog.String(contest.name);
  1037. KernelLog.String(" is full!"); KernelLog.Ln() END; *)
  1038. tempAddr:= SYSTEM.GET32(packet.blockBufferAddr);
  1039. (* Check if the context is running, else wake it up *)
  1040. (* KernelLog.String("Printing the content of the control set register before setting the run bit:");
  1041. FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(contest.ctrlSet)); KernelLog.Ln(); *)
  1042. IF ~(isRunning IN FirewireLowUtil.ReadReg(contest.ctrlSet)) THEN (* KernelLog.String("Starting "); KernelLog.String(contest.name);
  1043. KernelLog.String(" contest!"); KernelLog.Ln();
  1044. KernelLog.String("The comamnd Ptr is: "); FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,contest.prgr.bufferAddr+z));
  1045. KernelLog.Ln(); *)
  1046. FirewireLowUtil.WriteReg(contest.cmdPtr,FirewireLowUtil.ConvertToSet(packet.blockBufferAddr + z));
  1047. (* KernelLog.String("The content of the ctrl set register is: ");
  1048. FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(contest.ctrlSet)); KernelLog.Ln(); *)
  1049. IF FirewireLowUtil.StartContest(contest) THEN (* KernelLog.String("The context started successfully!"); KernelLog.Ln(); *)
  1050. ELSE KernelLog.String("The context didn't start successfully!"); KernelLog.Ln();
  1051. END
  1052. ELSE (* wake up context *)
  1053. IF ~(active IN FirewireLowUtil.ReadReg(contest.ctrlSet)) THEN (* KernelLog.String("Waking up ");
  1054. KernelLog.String(contest.name); KernelLog.Ln() *)
  1055. ELSE (* KernelLog.String("The context "); KernelLog.String(contest.name); KernelLog.String(" is already active!");
  1056. KernelLog.Ln(); *)
  1057. END;
  1058. (* KernelLog.String("The comamnd Ptr is: "); FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,contest.prgr.bufferAddr+z));
  1059. KernelLog.Ln(); *)
  1060. FirewireLowUtil.WriteReg(contest.ctrlSet,{12}); (* wake *)
  1061. END;
  1062. (* KernelLog.String("Leaving FillFifo!"); KernelLog.Ln(); *)
  1063. RETURN error;
  1064. END FillFifo;
  1065. (** Decides if it's a local or external 1394 packet. IF it's an external packet it will be sent to the OHCI send procedures *)
  1066. PROCEDURE SendPacket1394(context: Contest;VAR packet: OHCIPacket):BOOLEAN; (* core.c *)
  1067. CONST queued = 0;
  1068. VAR speed: LONGINT;
  1069. BEGIN
  1070. IF packet.host.inBusReset
  1071. OR (packet.generation # SYSTEM.VAL(LONGINT,LSH(FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount)*{16..23},-16))) THEN
  1072. KernelLog.String("Generation mismatch or host in bus reset!"); KernelLog.Ln(); RETURN FALSE
  1073. END;
  1074. packet.state:= FirewireLowUtil.QUEUED;
  1075. IF ( SYSTEM.VAL(LONGINT,packet.nodeID) = packet.host.nodeID ) THEN (* It's a local request *)
  1076. KernelLog.String("It's an internal packet!"); KernelLog.Ln(); (*
  1077. size:= packet.dataSize + packet.headerSize;
  1078. SYSTEM.MOVE(packet.header, ConvertToLongint(tempBuf), packet.headerSize);
  1079. IF packet.dataSize > 0 THEN
  1080. SYSTEM.MOVE(packet.data, ConvertToLongint(tempBuf)+packet.headerSize, packet.dataSize)
  1081. END;
  1082. IF packet.respExpected THEN ack:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.AckPending)
  1083. ELSE ack:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.AckComplete)
  1084. END;
  1085. PacketSent(context,packet,ack);
  1086. PacketReceived(context,tempBuf,size,FALSE);
  1087. RETURN TRUE *)
  1088. RETURN FALSE
  1089. END;
  1090. IF (packet.type = FirewireLowUtil.async) & (packet.nodeID # {0..5}) THEN
  1091. speed:= OHCI.SpeedMap[OHCI.nodeID][SYSTEM.VAL(LONGINT,packet.nodeID)];
  1092. packet.speed:= FirewireLowUtil.ConvertToSet(speed);
  1093. END;
  1094. (* IF (speed = 1) OR (speed = 2) THEN
  1095. speed:= speed*200;
  1096. KernelLog.String("Sending packet with speed: "); KernelLog.Int(speed,2); KernelLog.String("!"); KernelLog.Ln()
  1097. ELSE KernelLog.String("Sending packt with speed: 100!"); KernelLog.Ln()
  1098. END; *)
  1099. (*
  1100. CASE speed OF
  1101. 0: KernelLog.String("Sending packet with speed: 100!"); KernelLog.Ln()
  1102. |1: KernelLog.String("Sending packet with speed: 200!"); KernelLog.Ln()
  1103. |2: KernelLog.String("Sending packet with speed: 400!"); KernelLog.Ln()
  1104. END; *)
  1105. (*
  1106. KernelLog.String("Dumping the packet::SendPacket1394!"); KernelLog.Ln();
  1107. FOR i:= 0 TO (packet.headerSize DIV 4)-1 DO
  1108. FirewireLowUtil.PrintSet(packet.header[i])
  1109. END;
  1110. IF packet.dataSize > 0 THEN
  1111. FOR i:= 0 TO (packet.dataSize DIV 4)-1 DO
  1112. FirewireLowUtil.PrintSet(packet.data[i])
  1113. END
  1114. ELSE KernelLog.String("PacketDataSize is: "); KernelLog.Int(packet.dataSize,2); KernelLog.Ln();
  1115. END; *)
  1116. RETURN OHCISend(packet);
  1117. END SendPacket1394;
  1118. (** Allocates a buffer for the configuration rom *)
  1119. PROCEDURE ConfigRomAlloc;
  1120. VAR buffer: FirewireLowUtil.CharBuffer; adr: ADDRESS; s: SET;
  1121. BEGIN
  1122. (* KernelLog.String("Entering configuration rom allocation"); KernelLog.Ln(); *)
  1123. (* Allocating 2k buffer *)
  1124. NEW(buffer, 2048);
  1125. (* find a 1K aligned address *)
  1126. adr:= ADDRESSOF(buffer[0]);
  1127. DEC(adr,adr MOD 1024);
  1128. INC(adr,1024);
  1129. s:= SYSTEM.VAL(SET,adr);
  1130. (* setting the buffer address *)
  1131. (* KernelLog.String("Printing the buffer address"); KernelLog.Ln();
  1132. FirewireLowUtil.PrintSet(s); *)
  1133. OHCI.ptrToConfigRomBuf:= buffer;
  1134. OHCI.ConfigRomBufferAdr:= s;
  1135. END ConfigRomAlloc;
  1136. (** Initializes the asynchronous receive request/response descriptors *)
  1137. PROCEDURE InitARRDesc;
  1138. CONST cmd = {29}; s = {27}; i = {21,20}; b = {19,18}; reqCount = {9}; resCount = {9};
  1139. VAR desc: FirewireLowUtil.InputMoreDesc;
  1140. BEGIN
  1141. (* Input more AR *)
  1142. desc.cmd := cmd; desc.s := s; desc.b := b;
  1143. (* Input more *)
  1144. desc.i := i; desc.reqCount := reqCount; desc.resCount := resCount;
  1145. OHCI.IMDesc:= desc;
  1146. END InitARRDesc;
  1147. (** Configure the asynchronous receive request/response contexts *)
  1148. PROCEDURE ConfigARR;
  1149. VAR reqCont, resCont: FirewireLowUtil.Contest; controller: FirewireLowUtil.ADMAController; size: LONGINT;
  1150. BEGIN
  1151. OHCI.ARDescNum:= 4;
  1152. InitARRDesc();
  1153. (* Initialize contest with a scheduling buffer with place for 10 packets *)
  1154. OHCI.MaxPacketSize:= FirewireLowUtil.GetMaxPcktSize();
  1155. size:= 10;
  1156. NEW(controller,size,OHCI.ARDescNum);
  1157. OHCI.ARController:= controller;
  1158. (* Initialize request contest *)
  1159. reqCont:= OHCI.ARController.GetReqContest();
  1160. reqCont.type:= FirewireLowUtil.REQ;
  1161. reqCont.name := "AR request";
  1162. reqCont.cmdPtr:= FirewireLowUtil.ARReqComPtr;
  1163. reqCont.ctrlSet:= FirewireLowUtil.ARReqContCtrlSet;
  1164. reqCont.ctrlClear:= FirewireLowUtil.ARReqContCtrlClear;
  1165. (* Initialize response contest *)
  1166. reqCont.type:= FirewireLowUtil.RES;
  1167. resCont:= OHCI.ARController.GetResContest();
  1168. resCont.name:= "AR response";
  1169. resCont.cmdPtr:= FirewireLowUtil.ARResComPtr;
  1170. resCont.ctrlSet:= FirewireLowUtil.ARResContCtrlSet;
  1171. resCont.ctrlClear:= FirewireLowUtil.ARResContCtrlClear;
  1172. (* Allocate buffers for programs and packets *)
  1173. resCont.prgr.SetBufferAddr(FirewireLowUtil.AllocARResBuf(resCont.prgr.ptrToBuf));
  1174. reqCont.prgr.SetBufferAddr(FirewireLowUtil.AllocARReqBuf(reqCont.prgr.ptrToBuf));
  1175. FirewireLowUtil.AllocPcktBuf(1,reqCont.tempBuffer,reqCont.ptrToTmpBuf);
  1176. FirewireLowUtil.AllocPcktBuf(1,resCont.tempBuffer,resCont.ptrToTmpBuf);
  1177. END ConfigARR;
  1178. (** Configure the asynchronous transmit request/response contexts *)
  1179. PROCEDURE ConfigATR;
  1180. VAR reqCont, resCont: FirewireLowUtil.Contest; controller: FirewireLowUtil.ADMAController; size : LONGINT;
  1181. BEGIN
  1182. OHCI.ATDescNum:= 32;
  1183. (* Initialize contest with a scheduling buffer with place for 10 packets *)
  1184. size:= 10;
  1185. NEW(controller,size,OHCI.ATDescNum);
  1186. OHCI.ATController:= controller;
  1187. (* Initialize request contest *)
  1188. reqCont:= OHCI.ATController.GetReqContest();
  1189. reqCont.type:= FirewireLowUtil.REQ;
  1190. reqCont.name:= "AT request";
  1191. reqCont.cmdPtr:= FirewireLowUtil.ATReqComPtr;
  1192. reqCont.ctrlSet:= FirewireLowUtil.ATReqContCtrlSet;
  1193. reqCont.ctrlClear:= FirewireLowUtil.ATReqContCtrlClear;
  1194. (* Initialize response contest *)
  1195. resCont:= OHCI.ATController.GetResContest();
  1196. resCont.type:= FirewireLowUtil.RES;
  1197. resCont.name:= "AT response";
  1198. resCont.cmdPtr:= FirewireLowUtil.ATResComPtr;
  1199. resCont.ctrlSet:= FirewireLowUtil.ATResContCtrlSet;
  1200. resCont.ctrlClear:= FirewireLowUtil.ATResContCtrlClear;
  1201. (* Allocate buffers for programs and packets *)
  1202. resCont.prgr.SetBufferAddr(FirewireLowUtil.AllocATResBuf(resCont.prgr.ptrToBuf));
  1203. reqCont.prgr.SetBufferAddr(FirewireLowUtil.AllocATReqBuf(reqCont.prgr.ptrToBuf));
  1204. END ConfigATR;
  1205. (** Configures the isochronous receive contexts *)
  1206. PROCEDURE ConfigIR;
  1207. VAR contest: FirewireLowUtil.IRContest; controller: FirewireLowUtil.IRDMAController; size, avIRCont, i: LONGINT;
  1208. str: ARRAY 5 OF CHAR;
  1209. BEGIN
  1210. avIRCont:= FirewireLowUtil.GetAvailableIRCont();
  1211. size:= 10; i:= 0;
  1212. OHCI.IRDescNum:= 16;
  1213. NEW(controller,avIRCont,size,OHCI.IRDescNum);
  1214. OHCI.IRController:= controller;
  1215. WHILE controller.hasNext DO contest:= controller.GetNextContest();
  1216. contest.type:= FirewireLowUtil.ISO;
  1217. contest.name:= "IR "; Strings.IntToStr(i,str); Strings.Append(str,contest.name);
  1218. contest.cmdPtr:= FirewireLowUtil.IRComPtr+(32*i);
  1219. contest.ctrlSet:= FirewireLowUtil.isochRecvCntCtrlSet+(32*i);
  1220. contest.ctrlClear:= FirewireLowUtil.isochRecvCntCtrlClear+(32*i);
  1221. contest.match:= FirewireLowUtil.isochRecvContMatch+(32*i);
  1222. contest.prgr.SetBufferAddr(FirewireLowUtil.AllocIRBuf(contest.prgr.ptrToBuf,OHCI.IRDescNum));
  1223. INC(i);
  1224. END;
  1225. (* FirewireLowUtil.AllocPcktBuf(OHCI.IRDescNum*avIRCont, OHCI.IRPcktBuf); *)
  1226. END ConfigIR;
  1227. (** Configure the isochronous transmit contexts *)
  1228. PROCEDURE ConfigIT;
  1229. VAR contest: FirewireLowUtil.Contest; controller: FirewireLowUtil.ITDMAController; size, avITCont, i: LONGINT;
  1230. str: ARRAY 5 OF CHAR;
  1231. BEGIN
  1232. avITCont:= FirewireLowUtil.GetAvailableITCont();
  1233. size:= 10; i:= 0;
  1234. OHCI.ITDescNum:= 16;
  1235. NEW(controller,avITCont,size,OHCI.ITDescNum);
  1236. OHCI.ITController:= controller;
  1237. WHILE controller.hasNext DO contest:= controller.GetNextContest();
  1238. contest.type:= FirewireLowUtil.ISO;
  1239. contest.name:= "IT "; Strings.IntToStr(i,str); Strings.Append(str,contest.name);
  1240. contest.cmdPtr:= FirewireLowUtil.ITComPtr+(16*i);
  1241. contest.ctrlSet:= FirewireLowUtil.isochXmitCntCtrlSet+(16*i);
  1242. contest.ctrlClear:= FirewireLowUtil.isochXmitCntCtrlClear+(16*i);
  1243. contest.prgr.SetBufferAddr(FirewireLowUtil.AllocITBuf(contest.prgr.ptrToBuf,OHCI.ITDescNum));
  1244. INC(i);
  1245. END;
  1246. (* FirewireLowUtil.AllocPcktBuf(OHCI.ITDescNum*avITCont, OHCI.ITPcktBuf); *)
  1247. END ConfigIT;
  1248. (** Generates the dma receive programs and starts the contexts *)
  1249. PROCEDURE InitAsyncRecvCont;
  1250. VAR i: LONGINT; desc: FirewireLowUtil.InputMoreDesc; s, Z, branchAddress, dataAddress:SET;
  1251. quadlet1, quadlet2, quadlet3, quadlet4, reqCount: SET; reqCntst, resCntst: FirewireLowUtil.Contest; block: FirewireLowUtil.Block;
  1252. branchAddressPtr: ADDRESS;
  1253. BEGIN
  1254. desc:= OHCI.IMDesc;
  1255. reqCntst:= OHCI.ARController.GetReqContest();
  1256. resCntst:= OHCI.ARController.GetResContest();
  1257. (* Stop contexts if not already stopped *)
  1258. (* KernelLog.String("Stopping arreq contest"); KernelLog.Ln(); *)
  1259. FirewireLowUtil.StopContext(reqCntst.ctrlClear);
  1260. (* KernelLog.String("Stopping arres contest"); KernelLog.Ln(); *)
  1261. FirewireLowUtil.StopContext(resCntst.ctrlClear);
  1262. (* Write descriptors for the asynchronous request context *)
  1263. block.descNum:= OHCI.ARDescNum;
  1264. block.start:= reqCntst.prgr.bufferAddr;
  1265. FOR i:= 0 TO OHCI.ARDescNum-1 DO
  1266. s:= desc.cmd + desc.s + desc.b;
  1267. reqCount:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.BufSize);
  1268. (* KernelLog.String("Getting buffer::InitAsyncRecvCont"); KernelLog.Ln(); *)
  1269. dataAddress:= reqCntst.buffers.GetBuffer();
  1270. (* KernelLog.String("Got buffer!"); KernelLog.Ln(); *)
  1271. quadlet1:= s + reqCount; quadlet2:= dataAddress; quadlet4:= reqCount;
  1272. IF i+1 = OHCI.ARDescNum THEN (* build a ring *)
  1273. quadlet3:= SYSTEM.VAL(SET,block.start) + {0}; block.end:= reqCntst.prgr.bufferAddr + i*16;
  1274. branchAddressPtr:= reqCntst.prgr.bufferAddr + i*16+8;
  1275. reqCntst.prgr.nextAddr:= reqCntst.prgr.bufferAddr + i*16+16;
  1276. (* Is this the last descriptor? *)
  1277. ELSE Z:= {0}; branchAddress:= FirewireLowUtil.ConvertToSet(reqCntst.prgr.bufferAddr + (i+1)*16);
  1278. quadlet3:= branchAddress + Z;
  1279. END;
  1280. SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16, quadlet1);
  1281. SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16+4, quadlet2);
  1282. SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16+8, quadlet3);
  1283. SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16+12, quadlet4);
  1284. END;
  1285. reqCntst.prgr.blockBuffer.Append(block);
  1286. block.descNum:= OHCI.ARDescNum;
  1287. block.start:= resCntst.prgr.bufferAddr;
  1288. (* Write descriptors for the asynchronous response context *)
  1289. FOR i:= 0 TO OHCI.ARDescNum-1 DO
  1290. s:= desc.cmd + desc.s + desc.b;
  1291. reqCount:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.BufSize);
  1292. dataAddress:= resCntst.buffers.GetBuffer();
  1293. quadlet1:= s + reqCount; quadlet2:= dataAddress; quadlet4:= reqCount;
  1294. IF i+1 = OHCI.ARDescNum THEN (* build a ring *)
  1295. quadlet3:= SYSTEM.VAL(SET,block.start)+{0}; block.end:= resCntst.prgr.bufferAddr + i*16;
  1296. branchAddressPtr:= resCntst.prgr.bufferAddr + i*16+8;
  1297. resCntst.prgr.nextAddr:= resCntst.prgr.bufferAddr + i*16+16;
  1298. (* Is this the last descriptor? *)
  1299. ELSE Z:= {0}; branchAddress:= FirewireLowUtil.ConvertToSet(resCntst.prgr.bufferAddr + (i+1)*16);
  1300. quadlet3:= branchAddress + Z;
  1301. END;
  1302. SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16, quadlet1);
  1303. SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16+4, quadlet2);
  1304. SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16+8, quadlet3);
  1305. SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16+12, quadlet4);
  1306. END;
  1307. resCntst.prgr.blockBuffer.Append(block);
  1308. (* Set the ARReq command ptr *)
  1309. s:= FirewireLowUtil.ConvertToSet(reqCntst.prgr.bufferAddr) + {0};
  1310. SYSTEM.PUT32(base + reqCntst.cmdPtr, s);
  1311. (* Start the ARReq context *)
  1312. ASSERT(FirewireLowUtil.StartContest(reqCntst));
  1313. (* Set the ARRes command ptr *)
  1314. s:= FirewireLowUtil.ConvertToSet(resCntst.prgr.bufferAddr) + {0};
  1315. SYSTEM.PUT32(base + resCntst.cmdPtr, s);
  1316. (* Start the ARReq context *)
  1317. ASSERT(FirewireLowUtil.StartContest(resCntst));
  1318. END InitAsyncRecvCont;
  1319. (** Initializes the isochronous receive contexts *)
  1320. PROCEDURE InitIsochRecvCont;
  1321. VAR i: LONGINT; desc: FirewireLowUtil.InputMoreDesc; s, Z, branchAddress, dataAddress:SET;
  1322. quadlet1, quadlet2, quadlet3, quadlet4, reqCount: SET; contest: FirewireLowUtil.IRContest; block: FirewireLowUtil.Block;
  1323. branchAddressPtr: ADDRESS;
  1324. BEGIN
  1325. OHCI.IRController.ResetIterator();
  1326. IF OHCI.IRController.hasNext THEN contest:= OHCI.IRController.GetNextContest() END;
  1327. desc:= OHCI.IMDesc;
  1328. (* Do not forget to start all other contexts too, if needed *)
  1329. (* Stop contexts if not already stopped *)
  1330. FirewireLowUtil.StopContext(contest.ctrlClear);
  1331. (* Write descriptors for the asynchronous request context *)
  1332. block.descNum:= OHCI.IRDescNum;
  1333. block.start:= contest.prgr.bufferAddr;
  1334. FOR i:= 0 TO OHCI.IRDescNum-1 DO
  1335. s:= desc.cmd + desc.s + desc.b + desc.i;
  1336. reqCount:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.BufSize);
  1337. (* dataAddress:= OHCI.IRPcktBuf[i]; *)
  1338. dataAddress:= contest.buffers.GetBuffer();
  1339. quadlet1:= s + reqCount; quadlet2:= dataAddress; quadlet4:= reqCount;
  1340. (* Is this the last descriptor? *)
  1341. IF i+1 = OHCI.IRDescNum THEN (* build a ring *)
  1342. quadlet3:= SYSTEM.VAL(SET,block.start)+{0}; block.end:= contest.prgr.bufferAddr + i*16;
  1343. branchAddressPtr:= contest.prgr.bufferAddr + i*16+8;
  1344. contest.prgr.nextAddr:= contest.prgr.bufferAddr + i*16+16;
  1345. ELSE Z:= {0}; branchAddress:= FirewireLowUtil.ConvertToSet(contest.prgr.bufferAddr + (i+1)*16);
  1346. quadlet3:= branchAddress + Z;
  1347. END;
  1348. SYSTEM.PUT32(contest.prgr.bufferAddr + i*16, quadlet1);
  1349. SYSTEM.PUT32(contest.prgr.bufferAddr + i*16+4, quadlet2);
  1350. SYSTEM.PUT32(contest.prgr.bufferAddr + i*16+8, quadlet3);
  1351. SYSTEM.PUT32(contest.prgr.bufferAddr + i*16+12, quadlet4);
  1352. END;
  1353. contest.prgr.blockBuffer.Append(block);
  1354. (* Set the IR command ptr *)
  1355. s:= FirewireLowUtil.ConvertToSet(contest.prgr.bufferAddr) + {0};
  1356. SYSTEM.PUT32(base + contest.cmdPtr, s);
  1357. (* Start the first IR context *)
  1358. ASSERT(FirewireLowUtil.StartContest(contest));
  1359. END InitIsochRecvCont;
  1360. (** Initializes the isochronous transmit context *)
  1361. PROCEDURE InitIsochXmitCont;
  1362. VAR i: LONGINT; contest: FirewireLowUtil.Contest;
  1363. BEGIN
  1364. OHCI.ITController.ResetIterator();
  1365. WHILE OHCI.ITController.hasNext DO contest:= OHCI.ITController.GetNextContest();
  1366. FirewireLowUtil.StopContext(contest.ctrlClear + i*16);
  1367. END
  1368. END InitIsochXmitCont;
  1369. (** Initializes the asynchronous transmit context *)
  1370. PROCEDURE InitAsyncXmitCont;
  1371. VAR reqCont, resCont: FirewireLowUtil.Contest;
  1372. BEGIN
  1373. reqCont:= OHCI.ATController.GetReqContest(); resCont:= OHCI.ATController.GetResContest();
  1374. (* KernelLog.String("Stopping atreq contest"); KernelLog.Ln(); *)
  1375. FirewireLowUtil.StopContext(reqCont.ctrlClear);
  1376. (* KernelLog.String("Stopping atres contest"); KernelLog.Ln(); *)
  1377. FirewireLowUtil.StopContext(resCont.ctrlClear);
  1378. END InitAsyncXmitCont;
  1379. (** Controls the status of the OHCI *)
  1380. PROCEDURE ControlStatus;
  1381. (* Not really used *)
  1382. END ControlStatus;
  1383. (** Checks if this node is bus manager *)
  1384. PROCEDURE FindNodeInfo;
  1385. CONST csrDone= 31;
  1386. VAR reg: SET; done: BOOLEAN;
  1387. BEGIN
  1388. (* First check who is Bus Manager *)
  1389. FirewireLowUtil.WriteReg(FirewireLowUtil.CSRData,{0..5});
  1390. FirewireLowUtil.WriteReg(FirewireLowUtil.CSRCompare,{0..5});
  1391. FirewireLowUtil.WriteReg(FirewireLowUtil.CSRControl,{});
  1392. (* Wait until compare swap operation has been done *)
  1393. reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRControl);
  1394. done:= FALSE;
  1395. WHILE ~done DO
  1396. IF csrDone IN reg THEN done:= TRUE ELSE
  1397. reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRControl)
  1398. END
  1399. END;
  1400. (* Read the bus manager ID *)
  1401. reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRData);
  1402. (* Print it out *)
  1403. (* KernelLog.String("Printing the bus manager id");
  1404. FirewireLowUtil.PrintSet(reg); *)
  1405. (* Print the node id to compare it *)
  1406. (* KernelLog.String("Printing the node id");
  1407. reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID);
  1408. reg:= reg*{0..5};
  1409. FirewireLowUtil.PrintSet(reg); *)
  1410. END FindNodeInfo;
  1411. (* Not used: it was intended as a packet scheduler
  1412. PROCEDURE Schedule(contest: FirewireLowUtil.Contest);
  1413. VAR block: FirewireLowUtil.Block; quadlet3,quadlet: SET; branchAddress, avlbl, resdl, i: LONGINT; packet: FirewireLowUtil.Packet;
  1414. dataAddress, copyAddress: LONGINT;
  1415. CONST notLast= 0; reqCount = {0..15}; resCount = {0..15}; branchMask = {4..31};
  1416. BEGIN
  1417. (* read value of Z *)
  1418. KernelLog.String("Scheduling a block, if there are any!"); KernelLog.Ln();
  1419. ASSERT(contest.prgr.blockBuffer.num > 0);
  1420. block:= contest.prgr.blockBuffer.Remove();
  1421. quadlet3:= SYSTEM.VAL(SET, SYSTEM.GET32(block.start + 8));
  1422. (* read value of reqCount and resCount *)
  1423. quadlet:= SYSTEM.VAL(SET, SYSTEM.GET32(block.start));
  1424. avlbl:= ConvertToLongint(quadlet*reqCount);
  1425. quadlet:= SYSTEM.VAL(SET, SYSTEM.GET32(block.start + 12));
  1426. resdl:= ConvertToLongint(quadlet*reqCount);
  1427. (* read data address *)
  1428. dataAddress:= SYSTEM.VAL(LONGINT, SYSTEM.GET32(block.start + 4));
  1429. (* schedule packet *)
  1430. copyAddress:= ADDRESSOF(packet);
  1431. FOR i:= 0 TO avlbl-resdl-1 DO (* SYSTEM.MOVE(dataAddress+i,copyAddress+i,8) *)
  1432. SYSTEM.PUT8(copyAddress+i,SYSTEM.GET8(dataAddress+i)) END;
  1433. PrintBuffer(FirewireLowUtil.ConvertToSet(dataAddress),(avlbl-resdl) DIV 4);
  1434. PrintBuffer(FirewireLowUtil.ConvertToSet(copyAddress),(avlbl-resdl) DIV 4);
  1435. branchAddress:= ConvertToLongint(branchMask*quadlet3);
  1436. IF avlbl > resdl THEN KernelLog.String("Appending packet"); KernelLog.Ln(); contest.procBuffer.Append(packet) END;
  1437. WHILE notLast IN quadlet3 DO
  1438. quadlet3:= SYSTEM.VAL(SET, SYSTEM.GET32(branchAddress + 8));
  1439. (* read value of reqCount and resCount *)
  1440. quadlet:= SYSTEM.VAL(SET, SYSTEM.GET32(branchAddress));
  1441. avlbl:= ConvertToLongint(quadlet*reqCount);
  1442. quadlet:= SYSTEM.VAL(SET, SYSTEM.GET32(branchAddress + 12));
  1443. resdl:= ConvertToLongint(quadlet*reqCount);
  1444. (* read data address *)
  1445. dataAddress:= SYSTEM.VAL(LONGINT, SYSTEM.GET32(branchAddress + 4));
  1446. FOR i:= 0 TO avlbl-resdl-1 DO SYSTEM.MOVE(dataAddress+i,copyAddress+i,8) END;
  1447. (* KernelLog.String("Difference between available and residual is: "); KernelLog.Int(avlbl - resdl,2); KernelLog.Ln(); *)
  1448. PrintBuffer(FirewireLowUtil.ConvertToSet(dataAddress),(avlbl-resdl) DIV 4);
  1449. PrintBuffer(FirewireLowUtil.ConvertToSet(copyAddress),(avlbl-resdl) DIV 4);
  1450. branchAddress:= ConvertToLongint(branchMask*quadlet3);
  1451. IF avlbl > resdl THEN KernelLog.String("Appending packet"); KernelLog.Ln(); contest.procBuffer.Append(packet) END
  1452. END;
  1453. contest.prgr.blockBuffer.Append(block);
  1454. END Schedule; *)
  1455. (** Schedules packets for isochronous contexts *)
  1456. PROCEDURE IsoSchedule(reg: SET);
  1457. VAR controller: FirewireLowUtil.IRDMAController; i: LONGINT;
  1458. BEGIN
  1459. (* This call will fail in PacketReceived, because implementation is missing *)
  1460. FOR i:= 0 TO controller.avIRCont-1 DO
  1461. IF i IN reg THEN ProcRcvdPckts(controller.GetContest(i)) END
  1462. END;
  1463. END IsoSchedule;
  1464. (** Does OHCI buffer allocation and context initialization *)
  1465. PROCEDURE DevInit;
  1466. VAR reg: SET; (* t: Kernel.Timer; *)
  1467. BEGIN
  1468. NEW(t);
  1469. (* KernelLog.String("Entering device initialization"); KernelLog.Ln(); *)
  1470. (* csr configuration rom allocation *)
  1471. ConfigRomAlloc();
  1472. (* self-id buffer allocation *)
  1473. SelfIDAlloc();
  1474. FirewireLowUtil.CheckSelfIDCount();
  1475. (* allocate contexts *)
  1476. (* initialize AR response and request context *)
  1477. ConfigARR();
  1478. (* initialize AT response and receive context *)
  1479. ConfigATR();
  1480. (* Do a softReset *)
  1481. FirewireLowUtil.SoftReset();
  1482. (*Give power to the Link Layer *)
  1483. (* KernelLog.String("Giving power to the link layer"); KernelLog.Ln(); *)
  1484. (* KernelLog.String("Control register before power: ");
  1485. FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(FirewireLowUtil.HCControl)); *)
  1486. reg := {};
  1487. INCL(reg, LPS);
  1488. FirewireLowUtil.SetHCControl(reg);
  1489. t.Sleep(50);
  1490. (* KernelLog.String("Control register after power: ");
  1491. FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(FirewireLowUtil.HCControl)); *)
  1492. (* Determine number of available IR and IT contexts *)
  1493. FirewireLowUtil.CheckAvailableIR();
  1494. FirewireLowUtil.CheckAvailableIT();
  1495. (* initialize IR context *)
  1496. ConfigIR();
  1497. (* initialize IT context *)
  1498. ConfigIT();
  1499. END DevInit;
  1500. (** Inits the OHCI data structure *)
  1501. PROCEDURE InitOHCI;
  1502. VAR i: LONGINT;
  1503. BEGIN
  1504. FOR i:= 0 TO 62 DO
  1505. OHCI.Nodes[i]:= NIL
  1506. END;
  1507. OHCI.selfIDComplete:= FALSE;
  1508. NEW(OHCI.adrCheck);
  1509. NEW(t);NEW(clock);
  1510. NEW(OHCI.packetFIFO,10);
  1511. (* Get max packet size *)
  1512. OHCI.MaxPacketSize:= FirewireLowUtil.GetMaxPcktSize();
  1513. NEW(OHCI.tempBuffer,OHCI.MaxPacketSize);
  1514. END InitOHCI;
  1515. (** Initializes the OHCI registers *)
  1516. PROCEDURE&Init*(base,irq:LONGINT);
  1517. CONST irmcCmcIsc = {31,30,29}; cycClkAcc = {16..23}; pmcBmc = {28,27}; postedWriteEnable= {18};
  1518. programPhyEnable= 23; aPhyEnhanceEnable= 22; rcvPhyPkt = 10; postedWriteErr = 8;
  1519. VAR reg:SET;
  1520. BEGIN
  1521. SELF.base:=base;
  1522. SELF.irq:=irq;
  1523. DevInit();
  1524. InitOHCI();
  1525. (* Install the handler *)
  1526. IF(irq >= 1) & (irq <= 15) THEN Objects.InstallHandler(SELF.HandleInterrupt, Machine.IRQ0+irq)
  1527. END;
  1528. (* Define some bus options *)
  1529. reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.BusOptions);
  1530. (* Enable IRMC, CMC and ISC *)
  1531. reg:= reg + irmcCmcIsc;
  1532. (* XXX: Set cyc clk acc to zero for now *)
  1533. reg:= reg - cycClkAcc;
  1534. (* Disable PMC and BMC *)
  1535. reg:= reg - pmcBmc;
  1536. FirewireLowUtil.WriteReg(FirewireLowUtil.BusOptions,reg);
  1537. (* Set the bus number *)
  1538. FirewireLowUtil.WriteReg(FirewireLowUtil.NodeID,busNumber);
  1539. (* Enable posted writes *)
  1540. FirewireLowUtil.SetHCControl(postedWriteEnable);
  1541. (* Clearing LinkControl *)
  1542. FirewireLowUtil.WriteReg(FirewireLowUtil.CLinkControl,{0..31});
  1543. (* Check if OHCI has enhanced register map 1394a *)
  1544. reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.HCControl);
  1545. IF programPhyEnable IN reg THEN OHCI.ExstRegMap:= TRUE;
  1546. IF ~(aPhyEnhanceEnable IN reg) THEN FirewireLowUtil.SetHCControl({aPhyEnhanceEnable}) END
  1547. ELSE OHCI.ExstRegMap:= FALSE
  1548. END; reg:= {};
  1549. (* Enable cycle timer and cycle master and set the IRM contender bit in self ID packets *)
  1550. (* Enable receive selfID packets outside bus reset *)
  1551. FirewireLowUtil.WriteReg(FirewireLowUtil.LinkControl,{10,20,21});
  1552. IF OHCI.ExstRegMap THEN FirewireLowUtil.SetPhyControl({10},{6}) END;
  1553. (* clearing interrupts *)
  1554. (* KernelLog.String("Clearing interrupts"); KernelLog.Ln(); *)
  1555. FirewireLowUtil.ClearIntEventAll();
  1556. FirewireLowUtil.ClearIntMaskAll();
  1557. (* Set SelfID dma buffer *)
  1558. (* KernelLog.String("Setting the Self ID Buffer"); *)
  1559. FirewireLowUtil.WriteReg(FirewireLowUtil.SelfIDBuffer,OHCI.SelfIDBufferAdr);
  1560. (* Enable SelfID dma *)
  1561. (* KernelLog.String("Enabling SelfID"); KernelLog.Ln(); *)
  1562. FirewireLowUtil.WriteReg(FirewireLowUtil.LinkControl,{rcvSelfID});
  1563. (* Do not accept phy packets into the AR request context clearing the rcvPhyPkt bit
  1564. FirewireLowUtil.WriteReg(FirewireLowUtil.CLinkControl,{10}); *)
  1565. (* Set bufferfill, isochHeader, multichannel for IR context 0 *)
  1566. FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvCntCtrlSet,{28,30,31});
  1567. (* Set all tags of the first isochronous receive match register *)
  1568. FirewireLowUtil.SetIsochRecvContMatch({28..31});
  1569. (* Clear the isochronous receive mask and event interrupt register *)
  1570. FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntEvntClear,{0..31});
  1571. FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntMaskClear,{0..31});
  1572. (* Clear the isochronouse transmit mask and event interrupt register *)
  1573. FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntEvntClear,{0..31});
  1574. FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntMaskClear,{0..31});
  1575. (* Clear the isochronous receive mutlichannel high and low mask *)
  1576. FirewireLowUtil.WriteReg(FirewireLowUtil.IRmultiChanMaskHiClear,{0..31});
  1577. FirewireLowUtil.WriteReg(FirewireLowUtil.IRmultiChanMaskLoClear,{0..31});
  1578. (* Initialize asynchronous receive dma *)
  1579. InitAsyncRecvCont();
  1580. InitAsyncXmitCont();
  1581. (* Initialize isochronous dma *)
  1582. InitIsochRecvCont();
  1583. InitIsochXmitCont();
  1584. (* Set the isochronous receive interrupt mask for context 0 *)
  1585. FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntMaskSet,{0});
  1586. (* Set the isochronous transmit interrupt mask for context 0 *)
  1587. FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntMaskSet,{0});
  1588. (* Receive asynchronous requests from all nodes *)
  1589. FirewireLowUtil.WriteReg(FirewireLowUtil.ARFilterHISet,{31});
  1590. (* Set the asynchronous trasmit retries register *)
  1591. reg:= FirewireLowUtil.MaxPhysRespRetries + FirewireLowUtil.MaxATReqRetries
  1592. + FirewireLowUtil.MaxATRespRetries;
  1593. FirewireLowUtil.WriteReg(FirewireLowUtil.ATRetries, reg);
  1594. (* Set the physical upper bound if implemented *)
  1595. FirewireLowUtil.WriteReg(FirewireLowUtil.PhyUpperBound,{16..31});
  1596. reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.PhyUpperBound);
  1597. (* FirewireLowUtil.PrintSet(reg); *)
  1598. IF reg = {16..31} THEN
  1599. (* KernelLog.String("The physical upper bound is: 48hFFFF 0000 0000"); KernelLog.Ln(); *)
  1600. ELSE (* KernelLog.String("The physical upper bound is: 48h0001 0000 0000"); KernelLog.Ln() *)
  1601. END;
  1602. (* Receive physical requests from every bys and every node *)
  1603. FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterHiSet,{0..30});
  1604. FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterLowSet,{0..31});
  1605. (* Set no byte swapping *)
  1606. FirewireLowUtil.WriteReg(FirewireLowUtil.HCControl,{30});
  1607. (* Enabling interrupts *)
  1608. (* KernelLog.String("Enabling interrupts"); KernelLog.Ln(); *)
  1609. FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{31});
  1610. reg:= {};
  1611. INCL(reg,unrecoverableError);
  1612. INCL(reg,busReset);
  1613. INCL(reg,regAccessFail);
  1614. INCL(reg,selfIDComplete);
  1615. INCL(reg,RSPkt);
  1616. INCL(reg,RQPkt);
  1617. INCL(reg,respTxComplete);
  1618. INCL(reg,reqTxComplete);
  1619. INCL(reg,isochRx);
  1620. INCL(reg,isochTx);
  1621. INCL(reg,cycleInconsistent);
  1622. INCL(reg,postedWriteErr);
  1623. FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,reg);
  1624. FirewireLowUtil.CheckIntMask();
  1625. FirewireLowUtil.CheckIntEvent();
  1626. (* Initialize the label pool of the OHCI *)
  1627. NEW(OHCI.labeler,63);
  1628. (* Initialize OHCI bus reset status *)
  1629. OHCI.inBusReset:= FALSE;
  1630. (*Enable Operation of the lInk Layer*)
  1631. (* KernelLog.String("Enabling operation of the link layer"); KernelLog.Ln(); *)
  1632. reg:= {};
  1633. INCL(reg, LinkEnable);
  1634. FirewireLowUtil.SetHCControl(reg);
  1635. (* KernelLog.String("Control register after enabling operation of the link layer:");
  1636. KernelLog.Ln();
  1637. FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(FirewireLowUtil.HCControl)); *)
  1638. (* Initiate bus reset *)
  1639. (* KernelLog.String("Initiating bus reset!"); KernelLog.Ln(); *)
  1640. FirewireLowUtil.SetPhyControl({8},{6});
  1641. (* Print OHCI information *)
  1642. (* PrintOHCIInfo(); *) BEGIN {EXCLUSIVE}
  1643. AWAIT(OHCI.selfIDComplete)
  1644. END;
  1645. (* KernelLog.String("Scanning nodes!"); KernelLog.Ln(); *)
  1646. ScanNodes();
  1647. KernelLog.String("Finished OHCI initialization"); KernelLog.Ln();
  1648. END Init;
  1649. (** Checks to see who is the bus manager and tries to become it if necessary. This procedure is not complete *)
  1650. PROCEDURE CheckBusManager;
  1651. CONST isRoot= 30;
  1652. VAR selfIDBuf: SET; reg: SET;nodeID,data: SET;countReg,selfIDSize,IRMID: SET; i,j,size: LONGINT;
  1653. BEGIN
  1654. nodeID:= FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{0..5};
  1655. OHCI.nodeID:= ConvertToLongint(nodeID);
  1656. (* Check if OHCI is root *)
  1657. reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{30};
  1658. (* Check if OHCI is IRM: note that contender bit must be set and link must be active *)
  1659. IF isRoot IN reg THEN OHCI.IsRoot:= TRUE; OHCI.IsIRM:= TRUE;
  1660. (* Now be fast and set the ID of the OHCI into the BusManagerID register *)
  1661. FirewireLowUtil.WriteReg(FirewireLowUtil.CSRData,nodeID);
  1662. FirewireLowUtil.WriteReg(FirewireLowUtil.CSRCompare,{0..5});
  1663. FirewireLowUtil.WriteReg(FirewireLowUtil.CSRControl,{});
  1664. IRMID:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRData);
  1665. IF IRMID = {0..5} THEN
  1666. OHCI.IsBM:= TRUE; IRMID:= nodeID ELSE OHCI.IsBM:= FALSE
  1667. END;
  1668. ELSE (* Find out if some other IRM contender has higher ID *)
  1669. selfIDBuf:= OHCI.SelfIDBufferAdr;
  1670. countReg:= FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount);
  1671. selfIDSize := LSH(countReg,-2);
  1672. selfIDSize := selfIDSize*{0..8};
  1673. size := ConvertToLongint(selfIDSize);
  1674. j:= 4;
  1675. (* Traverse self ID buffer *)
  1676. OHCI.IsIRM:= TRUE;
  1677. FOR i:= 0 TO size-2 DO
  1678. data := SYSTEM.VAL(SET, SYSTEM.GET32(ConvertToLongint(selfIDBuf)+j)); INC(j,8);
  1679. IF (11 IN data) & (22 IN data) THEN (* ok it's an IRM contender, check if ID is higher then mine *)
  1680. data:= LSH(data,-24)*{0..5};
  1681. IF OHCI.nodeID > ConvertToLongint(data) THEN (* shit, I'm not IRM *)
  1682. OHCI.IsIRM:= FALSE
  1683. END
  1684. END
  1685. END;
  1686. IF OHCI.IsIRM THEN (* be fast and set OHCI ID into the BusManagerID register *)
  1687. FirewireLowUtil.WriteReg(FirewireLowUtil.CSRData,nodeID);
  1688. FirewireLowUtil.WriteReg(FirewireLowUtil.CSRCompare,{0..5});
  1689. FirewireLowUtil.WriteReg(FirewireLowUtil.CSRControl,{});
  1690. IRMID:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRData);
  1691. IF IRMID = {0..5} THEN
  1692. OHCI.IsBM:= TRUE; IRMID:= nodeID ELSE OHCI.IsBM:= FALSE
  1693. END
  1694. ELSE (* Go and try to set the nodeId of the OHCI into the IRM *)
  1695. KernelLog.Ln();
  1696. END;
  1697. (* I'm not the bus manager *)
  1698. (* Get the topology map *)
  1699. OHCI.IsRoot:= FALSE; OHCI.IsIRM:= FALSE END;
  1700. (* TODO *)
  1701. END CheckBusManager;
  1702. (** Scans the unit directory *)
  1703. PROCEDURE ScanUnitDirectory(node: FirewireLowUtil.Node);
  1704. (* not really needed *)
  1705. END ScanUnitDirectory;
  1706. (** Processes the unit directory of each device on the bus *)
  1707. PROCEDURE ProcessUnitDirectory(VAR ud: FirewireLowUtil.UnitDirectory; node: FirewireLowUtil.Node; addrLow, addrHigh: SET; VAR id: LONGINT);
  1708. VAR length,addr,code,value,i: LONGINT; udTemp: FirewireLowUtil.UnitDirectory; context: Contest; buffer: SET;
  1709. BEGIN
  1710. (* KernelLog.String("Processing the unit directory!"); KernelLog.Ln(); *)
  1711. context:= OHCI.ATController.GetReqContest();
  1712. addr:= SYSTEM.VAL(LONGINT,addrLow);
  1713. (* Get the length of the unit directory *)
  1714. IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
  1715. KernelLog.String("There was an error::ProcessUnitDirectory"); KernelLog.Ln(); RETURN
  1716. END;
  1717. length:= SYSTEM.VAL(LONGINT,LSH(buffer,-16));
  1718. NEW(ud,length);
  1719. ud.addrLow:= addrLow;
  1720. ud.addrHigh:= addrHigh;
  1721. INC(id); ud.ID:= id;
  1722. (* increment address *)
  1723. INC(addr,4);
  1724. addrLow:= SYSTEM.VAL(SET,addr);
  1725. i:= 0;
  1726. WHILE length > 0 DO
  1727. IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
  1728. KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
  1729. END;
  1730. ud.udEntries[i]:= buffer;
  1731. code:= SYSTEM.VAL(LONGINT,LSH(buffer,-24));
  1732. value:= SYSTEM.VAL(LONGINT,buffer*{0..23});
  1733. CASE code OF
  1734. FirewireLowUtil.ConfigRomVendorID: ud.vendorID:= value;
  1735. |FirewireLowUtil.ConfigRomModelID: ud.modelID:= value;
  1736. |FirewireLowUtil.ConfigRomSpecifierID: ud.specifierID:= value;
  1737. |FirewireLowUtil.ConfigRomUnitSWVersion: ud.version:= value;
  1738. |FirewireLowUtil.ConfigRomDescriptorLeaf: (* TODO *)
  1739. |FirewireLowUtil.ConfigRomDescriptorDirectory: (* TODO *)
  1740. |FirewireLowUtil.ConfigRomLogicalUnitDirectory:
  1741. ud.hasLogicalUnitDir:= TRUE;
  1742. ProcessUnitDirectory(udTemp,node,SYSTEM.VAL(SET,addr+value*4),addrHigh,id);
  1743. (* inherit data if missing *)
  1744. IF udTemp.vendorID = 0 THEN udTemp.vendorID:= ud.vendorID END;
  1745. IF udTemp.modelID = 0 THEN udTemp.modelID:= ud.modelID END;
  1746. IF udTemp.specifierID = 0 THEN udTemp.specifierID:= ud.specifierID END;
  1747. IF udTemp.version = 0 THEN udTemp.version:= ud.version END;
  1748. ud.luns[udTemp.ID]:= udTemp;
  1749. ELSE (* NOTHING *)
  1750. END;
  1751. DEC(length); INC(addr,4); addrLow:= SYSTEM.VAL(SET,addr); INC(i);
  1752. END;
  1753. END ProcessUnitDirectory;
  1754. (** Process the root directory of each device on the bus *)
  1755. PROCEDURE ProcessRootDirectory(node: FirewireLowUtil.Node);
  1756. VAR context: Contest; buffer, addrLow, addrHigh: SET; code, value, addr, busInfoLength, rootDirLength, id: LONGINT;
  1757. ud: FirewireLowUtil.UnitDirectory;
  1758. BEGIN
  1759. (* KernelLog.String("Processing root directory"); KernelLog.Ln(); *)
  1760. id:= -1;
  1761. addrHigh:= FirewireLowUtil.CSRBaseHigh;
  1762. addrLow:= FirewireLowUtil.CSRBaseLow;
  1763. addrLow:= addrLow + FirewireLowUtil.CSRConfigRom;
  1764. addr:= SYSTEM.VAL(LONGINT,addrLow);
  1765. context:= OHCI.ATController.GetReqContest();
  1766. (* get the length of the bus info block *)
  1767. IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
  1768. KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
  1769. END;
  1770. busInfoLength:= SYSTEM.VAL(LONGINT,LSH(buffer,-24));
  1771. addr:= addr + 4 + busInfoLength*4;
  1772. addrLow:= SYSTEM.VAL(SET,addr);
  1773. (* now get the length of the root directory *)
  1774. IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
  1775. KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
  1776. END;
  1777. rootDirLength:= SYSTEM.VAL(LONGINT,LSH(buffer,-16));
  1778. INC(addr,4);
  1779. addrLow:= SYSTEM.VAL(SET,addr);
  1780. WHILE rootDirLength > 0 DO
  1781. IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
  1782. KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
  1783. END;
  1784. code:= SYSTEM.VAL(LONGINT,LSH(buffer,-24));
  1785. value:= SYSTEM.VAL(LONGINT,buffer*{0..23});
  1786. CASE code OF
  1787. FirewireLowUtil.ConfigRomVendorID: node.vendorID:= value; (* perhaps look also for a text leaf *)
  1788. |FirewireLowUtil.ConfigRomNodeCapabilities: node.capabilities:= SYSTEM.VAL(SET,value);
  1789. |FirewireLowUtil.ConfigRomUnitDirectory:
  1790. ProcessUnitDirectory(ud,node,SYSTEM.VAL(SET,addr + value*4),addrHigh,id);
  1791. node.uds[ud.ID]:= ud;
  1792. ELSE (* NOTHING *)
  1793. END;
  1794. DEC(rootDirLength); INC(addr,4); addrLow:= SYSTEM.VAL(SET,addr);
  1795. END;
  1796. END ProcessRootDirectory;
  1797. (** Scan the root directory *)
  1798. PROCEDURE ScanRootDirectory;
  1799. (* not really needed *)
  1800. END ScanRootDirectory;
  1801. (** Scan a node's directories *)
  1802. PROCEDURE ScanEachNode(physicalID: SET; generation: LONGINT);
  1803. VAR buffer: ARRAY 5 OF SET; bufferLength,i: LONGINT;
  1804. node: FirewireLowUtil.Node; found: BOOLEAN; guid: FirewireLowUtil.GUID;
  1805. BEGIN
  1806. (* KernelLog.String("Entering scan each node"); KernelLog.Ln(); *)
  1807. bufferLength:= 5;
  1808. IF ReadBusInfoBlock(OHCI,physicalID,generation,buffer,bufferLength) THEN RETURN END;
  1809. IF (buffer[1] # SYSTEM.VAL(SET,FirewireLowUtil.BusIDNumber)) THEN
  1810. KernelLog.String("This device an invalid bus id number::ScanEachNode!"); KernelLog.Ln()
  1811. END;
  1812. guid.high:= buffer[3]; guid.low:= buffer[4];
  1813. (* now find this node and update it or create it *)
  1814. i:= 0; found:= FALSE;
  1815. WHILE (OHCI.Nodes[i] # NIL) & ~found DO
  1816. node:= OHCI.Nodes[i];
  1817. IF (node.guid.low = guid.low) & (node.guid.high = guid.high) THEN
  1818. found:= TRUE
  1819. ELSE INC(i)
  1820. END
  1821. END;
  1822. IF found THEN (* update *)
  1823. (* KernelLog.String("Updating node"); KernelLog.Ln(); *)
  1824. node.Update(buffer[2],physicalID,generation);
  1825. ELSE (* create new *)
  1826. (* KernelLog.String("Creating new node"); KernelLog.Ln(); *)
  1827. NEW(node,guid,buffer[2],physicalID,generation); OHCI.Nodes[i]:= node;
  1828. END;
  1829. (* KernelLog.String("Leaving scan each node"); KernelLog.Ln(); *)
  1830. END ScanEachNode;
  1831. (** Scan all nodes on the bus *)
  1832. PROCEDURE ScanNodes*;
  1833. VAR i,generation: LONGINT; sid: FirewireLowUtil.SelfID; node: FirewireLowUtil.Node;
  1834. BEGIN
  1835. (* KernelLog.String("Entering scan nodes"); KernelLog.Ln(); *)
  1836. WHILE OHCI.TopologyMap[i] # NIL DO
  1837. sid:= OHCI.TopologyMap[i];
  1838. IF ~sid.extended & (sid.linkActive={0}) THEN
  1839. IF sid.physicalID # SYSTEM.VAL(SET,OHCI.nodeID) THEN
  1840. generation:= FirewireLowUtil.GetGeneration();
  1841. ScanEachNode(sid.physicalID,generation)
  1842. END
  1843. END;
  1844. INC(i)
  1845. END;
  1846. i:= 0;
  1847. WHILE OHCI.Nodes[i] # NIL DO
  1848. node:= OHCI.Nodes[i];
  1849. IF node.probe THEN ProcessRootDirectory(node) END; INC(i);
  1850. END;
  1851. (* i:= 0; j:= 0;
  1852. WHILE c.OHCI.Nodes[i] # NIL DO
  1853. node:= c.OHCI.Nodes[i];
  1854. KernelLog.String("Printing the guid: "); KernelLog.Ln();
  1855. FirewireLowUtil.PrintSet(node.guid.high); FirewireLowUtil.PrintSet(node.guid.low);
  1856. KernelLog.String("Printing the unit directories if there are any"); KernelLog.Ln();
  1857. WHILE node.uds[j] # NIL DO
  1858. KernelLog.String("Printing the specifier id: "); KernelLog.Int(node.uds[j].specifierID,2); KernelLog.Ln();
  1859. INC(j);
  1860. END;
  1861. INC(i);
  1862. END; *)
  1863. (* KernelLog.String("Leaving scan nodes"); KernelLog.Ln(); *)
  1864. END ScanNodes;
  1865. (** Builds the topology and the speed map *)
  1866. PROCEDURE BuildMaps;
  1867. VAR size,i,j,addr: LONGINT; quad,reg: SET; sid: FirewireLowUtil.SelfID; esid: FirewireLowUtil.ExtSelfID;
  1868. speed, children: ARRAY 64 OF LONGINT; c: LONGINT;
  1869. BEGIN
  1870. OHCI.numOfNodes:= 0;
  1871. (* KernelLog.String("Entering BuildMaps!"); KernelLog.Ln(); *)
  1872. addr:= SYSTEM.VAL(LONGINT,OHCI.SelfIDBufferAdr) + 4; (* first quadlet has only management info *)
  1873. (* Count the nodes and remember the ids *)
  1874. reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount);
  1875. (* mask the size *)
  1876. size:= SYSTEM.VAL(LONGINT,LSH(reg * {2..10},-2));
  1877. size:= ((size-1) DIV 2)-1; (* we just need to look at the first quadlet of each selfid packet *)
  1878. (* Initialize *)
  1879. (* KernelLog.String("Initializing the children array!"); KernelLog.Ln(); *)
  1880. FOR i:= 0 TO 64-1 DO children[i]:= 0 END;
  1881. (* KernelLog.String("Initializing topology map!"); KernelLog.Ln();
  1882. KernelLog.String("size is: ");KernelLog.Int(size,2); KernelLog.Ln();
  1883. KernelLog.String("Number of nodes is: "); KernelLog.Int(OHCI.numOfNodes,2); KernelLog.Ln(); *)
  1884. FOR i:= 0 TO size DO
  1885. quad:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+(i*8)));
  1886. IF 23 IN quad THEN NEW(esid,quad); OHCI.TopologyMap[i]:= esid;
  1887. ELSE
  1888. (* KernelLog.String("It's an sid, increase numOfNodes"); KernelLog.Ln(); *)
  1889. NEW(sid,quad); OHCI.TopologyMap[i]:= sid; INC(OHCI.numOfNodes);
  1890. (* KernelLog.String("Number of nodes is: "); KernelLog.Int(OHCI.numOfNodes,2); KernelLog.Ln(); *)
  1891. END;
  1892. END;
  1893. OHCI.TopologyMap[i]:= NIL;
  1894. i:= 0;
  1895. (* check if port is active and connected to child node *)
  1896. (* and remember how much direct children this node has *)
  1897. (* KernelLog.String("Initialize speed array!"); KernelLog.Ln(); *)
  1898. WHILE OHCI.TopologyMap[i] # NIL DO
  1899. sid:= OHCI.TopologyMap[i]; c:= 0;
  1900. IF sid.extended THEN
  1901. esid:= sid (FirewireLowUtil.ExtSelfID);
  1902. IF (esid.pa = {0,1}) THEN INC(children[i]) END;
  1903. IF (esid.pb = {0,1}) THEN INC(children[i]) END;
  1904. IF (esid.pc = {0,1}) THEN INC(children[i]) END;
  1905. IF (esid.pd = {0,1}) THEN INC(children[i]) END;
  1906. IF (esid.pe = {0,1}) THEN INC(children[i]) END;
  1907. IF (esid.pf = {0,1}) THEN INC(children[i]) END;
  1908. IF (esid.pg = {0,1}) THEN INC(children[i]) END;
  1909. IF (esid.ph = {0,1}) THEN INC(children[i]) END;
  1910. ELSE
  1911. (* KernelLog.String("It's not an extended sid"); KernelLog.Ln(); *)
  1912. IF (sid.p0 = {0,1}) THEN INC(children[i]) END;
  1913. IF (sid.p1 = {0,1}) THEN INC(children[i]) END;
  1914. IF (sid.p2 = {0,1}) THEN INC(children[i]) END;
  1915. speed[i]:= SYSTEM.VAL(LONGINT,sid.sp);
  1916. END;
  1917. (* Check if there are more packets from this node *)
  1918. IF ~(0 IN sid.m) THEN INC(i) END;
  1919. END;
  1920. (* Set the self mapping *)
  1921. (* KernelLog.String("Initializing the speed map!"); KernelLog.Ln();
  1922. KernelLog.String("Number of Nodes: ");KernelLog.Int(OHCI.numOfNodes,2); KernelLog.Ln(); *)
  1923. FOR i:= 0 TO OHCI.numOfNodes-1 DO
  1924. (* KernelLog.String("I is: "); KernelLog.Int(i,2); KernelLog.Ln();*)
  1925. OHCI.SpeedMap[i][i]:= speed[i];
  1926. END;
  1927. (* KernelLog.String("Find out max communication speed!"); KernelLog.Ln(); *)
  1928. (* count the total children of a node and find out the max comunication speed for each node pair *)
  1929. i:= OHCI.numOfNodes-2;
  1930. WHILE i >= 0 DO
  1931. c:= children[i];
  1932. FOR j:=1 TO c DO INC(children[i],children[i+j]);
  1933. IF speed[i] < speed[i+j] THEN speed[i+j]:= speed[i] END;
  1934. END;
  1935. DEC(i);
  1936. END;
  1937. (* KernelLog.String("Complete speed map!"); KernelLog.Ln(); *)
  1938. (* Fill speed capabilities in speed map *)
  1939. i:= 0; j:= 0;
  1940. FOR i:= 0 TO OHCI.numOfNodes-1 DO
  1941. FOR j:= 0 TO OHCI.numOfNodes-1 DO
  1942. IF i # j THEN
  1943. OHCI.SpeedMap[i][j]:= speed[j]
  1944. END
  1945. END
  1946. END;
  1947. END BuildMaps;
  1948. (** Transactions *)
  1949. (** Creates a Lock packet *)
  1950. PROCEDURE Lock1394(context: Contest; ohci: FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT; addrLow, addrHigh: SET; extCode: LONGINT;
  1951. VAR data: SET; VAR arg: SET):BOOLEAN;
  1952. VAR packet: OHCIPacket; success: BOOLEAN;
  1953. BEGIN
  1954. success:= FALSE;
  1955. packet:= FirewireLowUtil.MakeLockPacket(ohci,nodeID,addrLow,addrHigh,extCode,data,arg);
  1956. (* Dump data
  1957. KernelLog.String("Dumping the data:: Lock1394"); KernelLog.Ln();
  1958. FOR i:= 0 TO (packet.dataSize DIV 4)-1 DO
  1959. FirewireLowUtil.PrintSet(packet.data[i])
  1960. END; *)
  1961. packet.generation:= generation;
  1962. IF (~SendPacket1394(context,packet)) THEN (* something went wrong, so try it again *)
  1963. KernelLog.String("Something went wrong:: Lock1394"); KernelLog.Ln();
  1964. OHCI.labeler.FreeTransLabel(packet.tLabel);
  1965. RETURN success
  1966. ELSE KernelLog.String("Everything ok::Lock1394"); KernelLog.Ln();
  1967. END;
  1968. success:= FirewireLowUtil.TestIfSuccess(packet);
  1969. IF success THEN data:= packet.data[0] END;
  1970. (* Release Packet *)
  1971. OHCI.labeler.FreeTransLabel(packet.tLabel);
  1972. OHCI.packetFIFO.ReleasePacket(packet);
  1973. RETURN success
  1974. END Lock1394;
  1975. (** Creates a write packet *)
  1976. PROCEDURE Write1394*(context: Contest; ohci: FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT; VAR buffer: SET; addrLow, addrHigh: SET;
  1977. length: LONGINT):BOOLEAN;
  1978. VAR packet: OHCIPacket; success: BOOLEAN; tries: LONGINT;
  1979. BEGIN
  1980. success:= FALSE; tries:= 0;
  1981. IF length = 0 THEN RETURN success END;
  1982. (* KernelLog.String("Write1394"); KernelLog.Ln();
  1983. FirewireLowUtil.PrintSet(addrHigh);
  1984. FirewireLowUtil.PrintSet(addrLow); *)
  1985. packet:= FirewireLowUtil.MakeWritePacket(ohci,nodeID,addrLow,addrHigh,buffer,length);
  1986. packet.generation:= generation;
  1987. WHILE (~success) & (tries < 4) DO
  1988. (* IF (~SendPacket1394(context,packet)) THEN (* something went wrong, so try it again *)
  1989. KernelLog.String("Something went wrong:: Write1394"); KernelLog.Ln();
  1990. OHCI.labeler.FreeTransLabel(packet.tLabel);
  1991. RETURN success
  1992. ELSE (* KernelLog.String("Everything ok::Write1394"); KernelLog.Ln(); *) *)
  1993. IF (SendPacket1394(context,packet)) THEN success:= TRUE
  1994. ELSE INC(tries); KernelLog.String("Something went wrong:: Write1394"); KernelLog.Ln();
  1995. END
  1996. END;
  1997. IF ~success THEN
  1998. KernelLog.String("Something went wrong:: Write1394"); KernelLog.Ln();
  1999. OHCI.labeler.FreeTransLabel(packet.tLabel);
  2000. RETURN success
  2001. END;
  2002. success:= FirewireLowUtil.TestIfSuccess(packet);
  2003. IF ~success THEN KernelLog.String("Not successfull:: Read1394"); KernelLog.Ln(); END;
  2004. (* Release Packet *)
  2005. OHCI.labeler.FreeTransLabel(packet.tLabel);
  2006. OHCI.packetFIFO.ReleasePacket(packet);
  2007. RETURN success
  2008. END Write1394;
  2009. (** Creates a read packet *)
  2010. PROCEDURE Read1394*(context: Contest; ohci: FirewireLowUtil.OHCIDesc; nodeID: SET;generation: LONGINT; addrLow,addrHigh:SET;
  2011. VAR buffer: SET; length: LONGINT):BOOLEAN;
  2012. VAR packet: OHCIPacket; success: BOOLEAN; tries,i: LONGINT;
  2013. BEGIN
  2014. (* KernelLog.String("Read1394"); KernelLog.Ln(); *)
  2015. success:= FALSE; tries:= 0;
  2016. IF length = 0 THEN RETURN success END;
  2017. packet:= FirewireLowUtil.MakeReadPacket(ohci,nodeID,addrLow,addrHigh,length);
  2018. packet.generation:= generation;
  2019. WHILE (~success) & (tries < 4) DO
  2020. (*IF (~SendPacket1394(context,packet)) THEN (* something went wrong, so try it again *)
  2021. KernelLog.String("Something went wrong:: Read1394"); KernelLog.Ln();
  2022. OHCI.labeler.FreeTransLabel(packet.tLabel);
  2023. RETURN success
  2024. ELSE (* KernelLog.String("Everything ok::Read1394"); KernelLog.Ln(); *) *)
  2025. IF (SendPacket1394(context,packet)) THEN success:= TRUE
  2026. ELSE INC(tries)
  2027. END
  2028. END;
  2029. IF ~success THEN
  2030. KernelLog.String("Something went wrong:: Read1394"); KernelLog.Ln();
  2031. OHCI.labeler.FreeTransLabel(packet.tLabel);
  2032. RETURN success
  2033. END;
  2034. success:= FirewireLowUtil.TestIfSuccess(packet);
  2035. IF success THEN
  2036. (* KernelLog.String("Packet was successfull::read1394"); KernelLog.Ln(); *)
  2037. IF length = 4 THEN (* It's a read quadlet packet *)
  2038. buffer:= packet.header[3];
  2039. ELSE (* It's a read block packet *) (* in this case buffer is an address *)
  2040. FOR i:= 0 TO (length DIV 4)-1 DO
  2041. SYSTEM.PUT32(ConvertToLongint(buffer) + i*4,packet.data[i])
  2042. END
  2043. END
  2044. ELSE KernelLog.String("Packet was not successfull!"); KernelLog.Ln();
  2045. END;
  2046. (* Release Packet *)
  2047. OHCI.labeler.FreeTransLabel(packet.tLabel);
  2048. OHCI.packetFIFO.ReleasePacket(packet);
  2049. RETURN success
  2050. END Read1394;
  2051. (** Node manager relative part *)
  2052. (** Sends a read quadlet packet *)
  2053. PROCEDURE NodeManagerReadQ(context: Contest; host:FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT;
  2054. addrLow,addrHigh: SET; VAR quad: SET):BOOLEAN;
  2055. VAR success: BOOLEAN; i: LONGINT;
  2056. BEGIN
  2057. success:= FALSE; i:= 0;
  2058. WHILE ~success & (i < 4) DO
  2059. success:= Read1394(context,host,nodeID,generation,addrLow,addrHigh,quad,4);
  2060. IF ~success THEN INC(i) END;
  2061. END;
  2062. IF i>=1 THEN KernelLog.String("Something went wrong::NodeManagerReadQ"); KernelLog.Ln()
  2063. ELSE (* KernelLog.String("Everything ok::NodeManagerReadQ"); KernelLog.Ln(); *)
  2064. END;
  2065. RETURN success
  2066. END NodeManagerReadQ;
  2067. (** Reads the bus info block of a node *)
  2068. PROCEDURE ReadBusInfoBlock(host: FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT; VAR buffer: ARRAY OF SET;
  2069. bufferLength: LONGINT):BOOLEAN;
  2070. VAR addrLow,addrHigh, base: SET; i, headerSize: LONGINT; vendorID: LONGINT; context: Contest;
  2071. BEGIN
  2072. addrHigh:= FirewireLowUtil.CSRBaseHigh;
  2073. addrLow:= FirewireLowUtil.CSRBaseLow + FirewireLowUtil.CSRConfigRom;
  2074. (*
  2075. KernelLog.String("The base low address is: "); FirewireLowUtil.PrintSet(addrLow); KernelLog.Ln();
  2076. KernelLog.String("The base high address is: "); FirewireLowUtil.PrintSet(addrHigh); KernelLog.Ln();
  2077. KernelLog.String("Reading bus info block of node with nodeID: "); KernelLog.Int(SYSTEM.VAL(LONGINT,nodeID),2);
  2078. KernelLog.Ln(); *)
  2079. buffer[0]:= {};
  2080. context:= OHCI.ATController.GetReqContest();
  2081. (* sometimes the device is not ready yet *)
  2082. WHILE (buffer[0] = {}) & (i<1) DO
  2083. IF ~NodeManagerReadQ(context,host,nodeID,generation,addrLow,addrHigh,buffer[0]) THEN
  2084. KernelLog.String("Quadlet read error!"); KernelLog.Ln(); INC(i) END;
  2085. END;
  2086. (* KernelLog.String("(((((((((((((((((((((((((Going on))))))))))))))))))))))))))))))))"); KernelLog.Ln(); *)
  2087. IF i>=1 THEN KernelLog.String("Error: DEVICE was not ready::ReadBusInfoBlock!");KernelLog.Ln();
  2088. RETURN TRUE
  2089. END;
  2090. headerSize:= SYSTEM.VAL(LONGINT,LSH(buffer[0],-24));
  2091. (* Increment address *)
  2092. addrLow:= SYSTEM.VAL(SET,SYSTEM.VAL(LONGINT,addrLow)+4);
  2093. IF headerSize = 1 THEN
  2094. (* KernelLog.String("Node has a minimal rom format!"); KernelLog.Ln(); *)
  2095. vendorID:= SYSTEM.VAL(LONGINT,buffer[0]*{0..23});
  2096. (* KernelLog.String("The vendor ID is: "); KernelLog.Int(vendorID,2); KernelLog.Ln(); *)
  2097. RETURN FALSE
  2098. END;
  2099. IF headerSize < 4 THEN
  2100. KernelLog.String("Non standard rom format, cannot parse!"); KernelLog.Ln(); RETURN TRUE
  2101. END;
  2102. FOR i:= 1 TO bufferLength-1 DO
  2103. (* KernelLog.String("Reading the quadlet number: "); KernelLog.Int(i,2); KernelLog.Ln(); *)
  2104. IF ~NodeManagerReadQ(context,host,nodeID,generation,addrLow,addrHigh,buffer[i]) THEN
  2105. KernelLog.String("Quadlet read error!"); KernelLog.Ln(); RETURN TRUE
  2106. END;
  2107. addrLow:= base + SYSTEM.VAL(SET,SYSTEM.VAL(LONGINT,addrLow)+4);
  2108. END;
  2109. vendorID:= SYSTEM.VAL(LONGINT,LSH(buffer[3],-8));
  2110. (* KernelLog.String("The vendorID is "); KernelLog.Int(vendorID,2); KernelLog.Ln(); *)
  2111. RETURN FALSE;
  2112. END ReadBusInfoBlock;
  2113. (** End node manager relative part *)
  2114. (** Prints OHCI information *)
  2115. PROCEDURE PrintOHCIInfo;
  2116. VAR reg: SET; val: LONGINT;
  2117. BEGIN
  2118. reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.Version);
  2119. KernelLog.String("Printing the OHCI information:"); KernelLog.Ln();
  2120. val:= LSH(ConvertToLongint(reg*{16..23}),-16);
  2121. KernelLog.String("OHCI version: "); KernelLog.Int(val,2); KernelLog.Ln();
  2122. val:= ConvertToLongint(reg*{0..7});
  2123. KernelLog.String("OHCI revision: "); KernelLog.Int(val,2); KernelLog.Ln();
  2124. IF 24 IN reg THEN KernelLog.String("The OHCI has an GUIDROM"); KernelLog.Ln(); END;
  2125. KernelLog.String("The OHCI is on interrupt: "); KernelLog.Int(irq,2); KernelLog.Ln();
  2126. KernelLog.String("The max packet size is: "); KernelLog.Int(OHCI.MaxPacketSize,2); KernelLog.Ln();
  2127. IF OHCI.ExstRegMap THEN
  2128. KernelLog.String("The OHCI has an exstended register map conform to 1394a."); KernelLog.Ln();
  2129. ELSE KernelLog.String("The OHCI has no exstended register map."); KernelLog.Ln();
  2130. END;
  2131. IF OHCI.IsRoot THEN
  2132. KernelLog.String("The OHCI is root."); KernelLog.Ln();
  2133. ELSE KernelLog.String("The OHCI is not root."); KernelLog.Ln()
  2134. END;
  2135. IF OHCI.IsIRM THEN
  2136. KernelLog.String("The OHCI is isochronous resource manager"); KernelLog.Ln();
  2137. ELSE KernelLog.String("The OHCI is not isochronous resource manager"); KernelLog.Ln()
  2138. END;
  2139. IF OHCI.IsBM THEN
  2140. KernelLog.String("The OHCI is bus manager"); KernelLog.Ln();
  2141. ELSE KernelLog.String("The OHCI is not bus manager"); KernelLog.Ln()
  2142. END
  2143. END PrintOHCIInfo;
  2144. (** Tests if access to a register was successfull *)
  2145. PROCEDURE TestAccess(name:ARRAY OF CHAR); (* not used *)
  2146. VAR reg:SET;
  2147. BEGIN
  2148. reg := FirewireLowUtil.ReadReg(FirewireLowUtil.IntEvent);
  2149. IF(18 IN reg) THEN KernelLog.String("RegAccess ");KernelLog.String(name);KernelLog.String(" failed");KernelLog.Ln;
  2150. ELSE KernelLog.String("RegAccess ");KernelLog.String(name);KernelLog.String(" successfull");KernelLog.Ln;
  2151. END
  2152. END TestAccess;
  2153. (** Removes the interrupt handler *)
  2154. PROCEDURE Cleanup;
  2155. BEGIN
  2156. Objects.RemoveHandler(HandleInterrupt,Machine.IRQ0+irq);
  2157. END Cleanup;
  2158. END Controller;
  2159. VAR c*:Controller;
  2160. (** Procedure to print the specifier ID of a node; not used *)
  2161. PROCEDURE ScanRomOfNodes*;
  2162. VAR j,i:LONGINT; node: FirewireLowUtil.Node;
  2163. BEGIN
  2164. c.ScanNodes();
  2165. (* Printing the content of the nodes array *)
  2166. i:= 0; j:= 0;
  2167. WHILE c.OHCI.Nodes[i] # NIL DO
  2168. node:= c.OHCI.Nodes[i];
  2169. KernelLog.String("Printing the guid: "); KernelLog.Ln();
  2170. (* FirewireLowUtil.PrintSet(node.guid.high); FirewireLowUtil.PrintSet(node.guid.low); *)
  2171. KernelLog.String("Printing the unit directories if there are any"); KernelLog.Ln();
  2172. WHILE node.uds[j] # NIL DO
  2173. KernelLog.String("Printing the specifier id: "); KernelLog.Int(node.uds[j].specifierID,2); KernelLog.Ln();
  2174. INC(j);
  2175. END;
  2176. INC(i);
  2177. END;
  2178. END ScanRomOfNodes;
  2179. (** Test procedure to send a ping packet *)
  2180. PROCEDURE SendPingPacket*;
  2181. VAR context: Contest;set0,set1,set2,set3,set4,set5,set6,set7: SET;
  2182. dataSize: LONGINT; packet: OHCIPacket; block: FirewireLowUtil.Block;
  2183. BEGIN
  2184. context:= c.OHCI.ATController.GetReqContest();
  2185. set0:= {28} + {25} + {23} + {20,21} + {18,19} + {2,3};
  2186. set1:= {};
  2187. set2:= {};
  2188. set3:= {};
  2189. set4:= {5,6,7};
  2190. set5:= {};
  2191. set6:= -set5;
  2192. set7:= {};
  2193. packet.type:= FirewireLowUtil.async;
  2194. dataSize:= 0;
  2195. block.start:= context.prgr.bufferAddr;
  2196. block.end:= block.start;
  2197. SYSTEM.PUT32(context.prgr.bufferAddr,set0);
  2198. SYSTEM.PUT32(context.prgr.bufferAddr+4,set1);
  2199. SYSTEM.PUT32(context.prgr.bufferAddr+8,set2);
  2200. SYSTEM.PUT32(context.prgr.bufferAddr+12,set3);
  2201. SYSTEM.PUT32(context.prgr.bufferAddr+16,set4);
  2202. SYSTEM.PUT32(context.prgr.bufferAddr+20,set5);
  2203. SYSTEM.PUT32(context.prgr.bufferAddr+24,set6);
  2204. SYSTEM.PUT32(context.prgr.bufferAddr+28,set7);
  2205. packet.block:= block;
  2206. FirewireLowUtil.WriteReg(context.cmdPtr,FirewireLowUtil.ConvertToSet(context.prgr.bufferAddr+2));
  2207. FirewireLowUtil.WriteReg(context.ctrlSet,{15});
  2208. context.listInserted.AddPacket(packet);
  2209. END SendPingPacket;
  2210. (** Test procedure to send a read packet *)
  2211. PROCEDURE SendReadPacket*;
  2212. VAR context: Contest; set0, set1, set2, set3, set4, set5, set6, set7: SET;
  2213. dataSize: LONGINT; packet: OHCIPacket; block: FirewireLowUtil.Block;
  2214. BEGIN
  2215. context:= c.OHCI.ATController.GetReqContest();
  2216. set0:= {28} + {25} + {20,21} + {18,19} + {2,3};
  2217. set1:= {};
  2218. set2:= {};
  2219. set3:= {};
  2220. set4:= {8} + {6};
  2221. set5:= {22..31} + {0..15};
  2222. set6:= {28..31} + {2,3,4,9}; (* bus manager id *)
  2223. set7:= {};
  2224. NEW(packet,16,0);
  2225. packet.type:= FirewireLowUtil.async;
  2226. packet.tLabel:= {}; packet.tCode:= {2};
  2227. dataSize:= 0;
  2228. block.start:= context.prgr.bufferAddr;
  2229. block.end:= block.start;
  2230. packet.header[0]:= set4;
  2231. packet.header[1]:= set5;
  2232. packet.header[2]:= set6;
  2233. packet.header[3]:= set7;
  2234. packet.name:= "vito";
  2235. SYSTEM.PUT32(context.prgr.bufferAddr,set0);
  2236. SYSTEM.PUT32(context.prgr.bufferAddr+4,set1);
  2237. SYSTEM.PUT32(context.prgr.bufferAddr+8,set2);
  2238. SYSTEM.PUT32(context.prgr.bufferAddr+12,set3);
  2239. SYSTEM.PUT32(context.prgr.bufferAddr+16,set4);
  2240. SYSTEM.PUT32(context.prgr.bufferAddr+20,set5);
  2241. SYSTEM.PUT32(context.prgr.bufferAddr+24,set6);
  2242. SYSTEM.PUT32(context.prgr.bufferAddr+28,set7);
  2243. packet.block:= block;
  2244. FirewireLowUtil.WriteReg(context.cmdPtr,FirewireLowUtil.ConvertToSet(context.prgr.bufferAddr+2));
  2245. context.listInserted.AddPacket(packet);
  2246. context.listAwaiting.AddPacket(packet);
  2247. IF ~context.listAwaiting.GetPacket(packet) THEN
  2248. KernelLog.String("Printing packet name: "); KernelLog.String(packet.name); KernelLog.Ln()
  2249. ELSE
  2250. KernelLog.String("We have a problem"); KernelLog.Ln()
  2251. END;
  2252. FirewireLowUtil.WriteReg(context.ctrlSet,{15});
  2253. END SendReadPacket;
  2254. (** Send a compare swap lock packet to hd to access maint-utility register *)
  2255. PROCEDURE SendLockPacket*;
  2256. VAR nodeID: SET; context: Contest; generation: LONGINT; addrLow, addrHigh: SET; extCode: LONGINT; data, arg: SET;
  2257. BEGIN
  2258. extCode:= 2H; (* compare swap extended transaction code *)
  2259. addrLow:= FirewireLowUtil.CSRBaseLow; addrHigh:= FirewireLowUtil.CSRBaseHigh;
  2260. (* set the address of the maint utility register *)
  2261. addrLow:= addrLow + {4,5,9};
  2262. context:= c.OHCI.ATController.GetReqContest();
  2263. nodeID:= {};
  2264. generation:= FirewireLowUtil.GetGeneration();
  2265. data:= {0..31}; arg:= {};
  2266. IF c.Lock1394(context,c.OHCI,nodeID,generation,addrLow,addrHigh,extCode,data,arg) THEN
  2267. KernelLog.String("First read was successfull::SendLockPacket"); KernelLog.Ln();
  2268. KernelLog.String("Printing old value: "); FirewireLowUtil.PrintSet(data); KernelLog.Ln()
  2269. ELSE
  2270. KernelLog.String("Something went wrong::SendLockPacket"); KernelLog.Ln();
  2271. END;
  2272. END SendLockPacket;
  2273. (** Test procedure to send a write packet *)
  2274. PROCEDURE SendWritePacket*;
  2275. VAR nodeID: SET; context: Contest; generation: LONGINT; addrLow, addrHigh: SET;
  2276. buffer: ARRAY 1 OF SET;
  2277. BEGIN
  2278. addrLow:= FirewireLowUtil.CSRBaseLow; addrHigh:= FirewireLowUtil.CSRBaseHigh;
  2279. (* set the address of the maint utility register *)
  2280. addrLow:= addrLow + {4,5,9};
  2281. context:= c.OHCI.ATController.GetReqContest();
  2282. nodeID:= {};
  2283. buffer[0]:= {0..31};
  2284. generation:= FirewireLowUtil.GetGeneration();
  2285. IF c.Write1394(context,c.OHCI,nodeID,generation,buffer[0],addrLow,addrHigh,4) THEN
  2286. KernelLog.String("Write was successfull::SendWritePacket"); KernelLog.Ln();
  2287. (* KernelLog.String("Printing old value: "); FirewireLowUtil.PrintSet(data); KernelLog.Ln() *)
  2288. ELSE
  2289. KernelLog.String("Something went wrong::SendLockPacket"); KernelLog.Ln();
  2290. END;
  2291. END SendWritePacket;
  2292. (** Test procedure to read the bus info block *)
  2293. PROCEDURE Test1394*;
  2294. VAR ohci: FirewireLowUtil.OHCIDesc; generation: LONGINT; sid: FirewireLowUtil.SelfID;
  2295. buffer: ARRAY 4 OF SET; i: LONGINT;
  2296. BEGIN
  2297. ohci:= c.OHCI; generation:= FirewireLowUtil.GetGeneration(); i:= 0;
  2298. WHILE ohci.TopologyMap[i] # NIL DO
  2299. IF ~(ohci.TopologyMap[i] IS FirewireLowUtil.ExtSelfID) &
  2300. (SYSTEM.VAL(LONGINT,ohci.TopologyMap[i].physicalID) # c.OHCI.nodeID) THEN
  2301. sid:= ohci.TopologyMap[i];
  2302. IF c.ReadBusInfoBlock(ohci,sid.physicalID,generation,buffer,4) THEN
  2303. KernelLog.String("There was a problem reading the bus info block::Test1394!"); KernelLog.Ln()
  2304. END
  2305. END;
  2306. INC(i);
  2307. END;
  2308. END Test1394;
  2309. (** Scan the PCI for 1394 devices *)
  2310. PROCEDURE ScanPCI(vendor,device: LONGINT);
  2311. VAR index, bus, dev, fct, base, irq: LONGINT; res: WORD;
  2312. BEGIN
  2313. index := 0;
  2314. WHILE(PCI.FindPCIDevice(device, vendor, index, bus, dev, fct) = PCI.Done) (*?*)
  2315. DO
  2316. (* KernelLog.String("Ok");
  2317. KernelLog.Ln; *)
  2318. res := PCI.ReadConfigDword(bus,dev,fct,PCI.Adr0Reg,base);
  2319. ASSERT(res = PCI.Done);
  2320. ASSERT(~ODD(base)); (* Operational registers mapped correctly in main memory memory space *)
  2321. DEC(base, base MOD 16);
  2322. Machine.MapPhysical(base,800H,SYSTEM.VAL(ADDRESS,base));
  2323. res := PCI.ReadConfigByte(bus,dev,fct,PCI.IntlReg,irq);
  2324. (* KernelLog.Int(irq,2);
  2325. KernelLog.Ln; *)
  2326. ASSERT(res = PCI.Done);
  2327. INC(index);
  2328. (* Set base in helper module *)
  2329. (* KernelLog.Int(base,2); *)
  2330. FirewireLowUtil.SetBase(base);
  2331. NEW(c,base,irq);
  2332. END;
  2333. END ScanPCI;
  2334. (** Dummy procedure *)
  2335. PROCEDURE Install*;
  2336. END Install;
  2337. (** Cleanup procedure *)
  2338. PROCEDURE Cleanup;
  2339. BEGIN
  2340. c.Cleanup();
  2341. END Cleanup;
  2342. (** Module initialization procedure *)
  2343. PROCEDURE Init;
  2344. BEGIN
  2345. (* KernelLog.String("Entering ScanPCI");
  2346. KernelLog.Ln; *)
  2347. ScanPCI(1106H,3044H);
  2348. END Init;
  2349. BEGIN
  2350. Modules.InstallTermHandler(Cleanup);
  2351. Init
  2352. END FirewireLow.
  2353. System.Free FirewireLow~
  2354. Builder.Compile \s *
  2355. Aos.Call FirewireLow.Install ~
  2356. Aos.Call FirewireLowUtil.PrintSelfIDCount ~
  2357. Aos.Call FirewireLow.TestReset ~
  2358. System.OpenKernelLog