MODULE FirewireLow;
IMPORT SYSTEM, KernelLog, Machine, PCI, Objects, Modules, FirewireLowUtil, Kernel, Strings;
CONST
MaxSelfIDErrors= 16;
busNumber= {6..15};
LinkEnable = 17;
LPS = 19;
masterIntEnable = 31;
reqTxComplete = 0;
respTxComplete = 1;
ARRQ = 2;
ARRS = 3;
RQPkt = 4;
RSPkt = 5;
isochTx = 6;
isochRx = 7;
postedWriteErr = 8;
lockRespErr = 9;
selfIDComplete2 = 15;
selfIDComplete = 16;
busReset = 17;
regAccessFail = 18;
phy = 19;
cycleSynch = 20;
cycle64Seconds = 21;
cycleLost = 22;
cycleInconsistent = 23;
unrecoverableError = 24;
cycleTooLong = 25;
phyRegRcvd = 26;
ackTardy = 27;
softInterrupt = 29;
rcvSelfID = 9;
TYPE
OHCIPacket = FirewireLowUtil.OHCIPacket;
Contest = FirewireLowUtil.Contest;
ListMember= FirewireLowUtil.ListMember;
Controller= OBJECT
VAR
base,irq:LONGINT; OHCI*: FirewireLowUtil.OHCIDesc; t: Kernel.Timer; timer: Kernel.MilliTimer;
timeout: BOOLEAN; clock: Objects.Timer;
PROCEDURE HandleTimeout;
VAR ms: LONGINT;
BEGIN {EXCLUSIVE}
ms:= Kernel.Left(timer);
IF ms <= 0 THEN
timeout := TRUE;
ELSE
Objects.SetTimeout(clock, SELF.HandleTimeout, ms)
END
END HandleTimeout;
PROCEDURE SelfIDAlloc;
VAR buffer: FirewireLowUtil.CharBuffer; adr: LONGINT; s: SET;
BEGIN
KernelLog.Ln();
NEW(buffer,10240);
adr := SYSTEM.ADR(buffer[0]);
DEC(adr,adr MOD 2048);
INC(adr,2048);
s := SYSTEM.VAL(SET,adr);
OHCI.SelfIDBufferAdr:= s;
OHCI.ptrToSelfIDBuf:= buffer;
OHCI.SelfIDErrors:= 0;
KernelLog.Ln();
END SelfIDAlloc;
PROCEDURE ReadSetQuadlet(address:LONGINT):SET;
BEGIN
RETURN SYSTEM.VAL(SET, SYSTEM.GET32(address));
END ReadSetQuadlet;
PROCEDURE CheckSelfIDStream():BOOLEAN;
CONST offsetSize = 2; selfIDError= 31; selfIDSizeMask = {0..8};
VAR selfIDSize, address, reg: SET; size: LONGINT; error: BOOLEAN;
BEGIN
error:= FALSE;
address := OHCI.SelfIDBufferAdr;
reg := FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount);
selfIDSize := SYSTEM.LSH(reg,-2);
selfIDSize := selfIDSize*selfIDSizeMask;
size := ConvertToLongint(selfIDSize);
IF CompareSelfIDGen(address,size) OR (selfIDError IN reg) THEN error:= TRUE;
IF OHCI.SelfIDErrors < MaxSelfIDErrors THEN INC(OHCI.SelfIDErrors);
KernelLog.String("There was an error checking the self id stream"); KernelLog.Ln();
ELSE KernelLog.String("Too much errors in self id process, giving up"); KernelLog.Ln();
END
END;
IF ~error THEN
OHCI.SelfIDErrors:= 0;
IF CheckIntegrity(address,size) THEN error:= TRUE;
KernelLog.String("There was an error checking the integrity of the self id stream"); KernelLog.Ln()
END
END;
RETURN error
END CheckSelfIDStream;
PROCEDURE PrintBuffer(address: SET; size: LONGINT);
VAR i, j, adr: LONGINT;
BEGIN
i:= 0;
j:= 0;
adr:= ConvertToLongint(address);
WHILE i < size DO FirewireLowUtil.PrintSet(SYSTEM.VAL(SET, SYSTEM.GET32(adr+j)));
INC(j,4); INC(i);
END
END PrintBuffer;
PROCEDURE CheckIntegrity(address: SET; size:LONGINT):BOOLEAN;
VAR i: LONGINT;data, invData : SET; error: BOOLEAN; j: LONGINT;
BEGIN
error:= FALSE;
j := 4;
i := 1;
WHILE i < size DO
data := SYSTEM.VAL(SET, SYSTEM.GET32(ConvertToLongint(address)+j)); INC(j,4);
invData:= SYSTEM.VAL(SET, SYSTEM.GET32(ConvertToLongint(address)+j));
IF ~(({0..31}-data) = invData) THEN
KernelLog.String("Integrity is broken"); KernelLog.Ln(); error:= TRUE; i:= size;
ELSE
END;
INC(j,4);
INC(i,2);
END;
RETURN error
END CheckIntegrity;
PROCEDURE CompareSelfIDGen(address:SET; size:LONGINT):BOOLEAN;
CONST selfIDGenMask = {16..23}; offsetGen = 16;
VAR header, selfIDGeneration: SET; i: LONGINT; error: BOOLEAN;
BEGIN
error:= FALSE;
header := SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(address)));
selfIDGeneration := header*selfIDGenMask;
i:= 0;
header := ReadSetQuadlet(ConvertToLongint(address));
header := header*selfIDGenMask;
IF ~(header = selfIDGeneration) THEN
KernelLog.String("selfIDGeneration mismatch");KernelLog.Ln(); error:= TRUE
END;
RETURN error;
END CompareSelfIDGen;
PROCEDURE ConvertToLongint(reg: SET):LONGINT;
BEGIN
RETURN SYSTEM.VAL(LONGINT,reg);
END ConvertToLongint;
PROCEDURE ProcSentPckts(contest: Contest) ;
VAR packet: OHCIPacket; status: SET; ack,dataSize: LONGINT; block: FirewireLowUtil.Block;
CONST acks= 4; code= {0..4};
BEGIN
WHILE ~contest.listInserted.GetPacket(packet) DO
dataSize:= packet.dataSize;
block:= packet.block;
IF (dataSize > 0) & (packet.type # FirewireLowUtil.raw) THEN
status:= SYSTEM.LSH(SYSTEM.VAL(SET, SYSTEM.GET32(block.end + 12)),-16)
ELSE status:= SYSTEM.LSH(SYSTEM.VAL(SET, SYSTEM.GET32(block.start + 12)),-16)
END;
IF (acks IN status) THEN ack:= SYSTEM.VAL(LONGINT,status*code);
ELSE
KernelLog.String("It's an event code!"); KernelLog.Ln();
CASE (ConvertToLongint(status*code)) OF
FirewireLowUtil.EvtNoStatus: KernelLog.String("No event status!"); KernelLog.Ln()
| FirewireLowUtil.EvtLongPacket: ack:= FirewireLowUtil.AckError;
KernelLog.String("The received data length was greater than the buffer's data length!");KernelLog.Ln()
| FirewireLowUtil.EvtMissingAck: ack:= FirewireLowUtil.AckError;
KernelLog.String("A subaction gap was detected before an ack arrived or the received ack had a parity error!");
KernelLog.Ln()
| FirewireLowUtil.EvtUnderrun: ack:= FirewireLowUtil.AckError;
KernelLog.String("Underrun on the corresponding FIFO. The packet was truncated!"); KernelLog.Ln()
| FirewireLowUtil.EvtOverrun: ack:= FirewireLowUtil.AckError;
KernelLog.String("A receive FIFO overflowed during the reception of an isochronous packet!"); KernelLog.Ln()
| FirewireLowUtil.EvtDescriptorRead: ack:= FirewireLowUtil.AckError;
KernelLog.String("An unrecoverable error occurred while the Host Controller was reading a descriptor block!");
KernelLog.Ln()
| FirewireLowUtil.EvtDataRead: ack:= FirewireLowUtil.AckError;
KernelLog.String("An error occurred while the Host Controller was attempting to"); KernelLog.Ln();
KernelLog.String(" read from host memory in the data stage of descriptor processing!"); KernelLog.Ln();
| FirewireLowUtil.EvtDataWrite: ack:= FirewireLowUtil.AckError;
KernelLog.String("An error occurred while the Host Controller was attempting to "); KernelLog.Ln();
KernelLog.String("write to host memory in the data stage of descriptor processing "); KernelLog.Ln();
KernelLog.String("or when processing a single 16-bit host memory write!"); KernelLog.Ln()
| FirewireLowUtil.EvtBusReset: ack:= FirewireLowUtil.AckError;
KernelLog.String("This is the synthesized bus reset packet!"); KernelLog.Ln();
| FirewireLowUtil.EvtTimeout: ack:= FirewireLowUtil.AckError;
KernelLog.String("This asynchronous transmit response packet expired and"); KernelLog.Ln();
KernelLog.String(" was not transmitted or an IT DMA context experienced "); KernelLog.Ln();
KernelLog.String("a skip processing overflow!"); KernelLog.Ln();
| FirewireLowUtil.EvtTcodeErr: ack:= FirewireLowUtil.AckError;
KernelLog.String("This packet has a bad event code!"); KernelLog.Ln()
| FirewireLowUtil.EvtUnknown: ack:= FirewireLowUtil.AckError;
KernelLog.String("Unknown error condition!"); KernelLog.Ln();
| FirewireLowUtil.EvtFlushed: ack:= FirewireLowUtil.AckError;
KernelLog.String("This packet was flushed due to a bus reset!"); KernelLog.Ln();
ELSE KernelLog.String("Unhandled or reserved event!"); KernelLog.Ln()
END;
RETURN
END;
PacketSent(contest,packet,FirewireLowUtil.ConvertToSet(ack));
ASSERT(~contest.listInserted.DelPacket(packet));
END;
IF FillFifo(contest) THEN
KernelLog.String("There was an error in FIllFifo"); KernelLog.Ln()
END;
END ProcSentPckts;
PROCEDURE ProcRcvdPckts(context: Contest);
VAR block: FirewireLowUtil.Block; i, bufSize, packetSize, resCount,packetBytesLeft, packetBytesRight: LONGINT;
bufferAddr, tCode,ack: SET; packetAddr,nextDesc: LONGINT; complete: BOOLEAN;
BEGIN
bufSize:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc)))*{0..15});
resCount:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 12))*{0..15});
packetSize:= FirewireLowUtil.PacketLength(context);
bufferAddr:= SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 4));
packetAddr:= ConvertToLongint(bufferAddr) + context.prgr.packetOffset;
tCode:= SYSTEM.VAL(SET,SYSTEM.LSH(SYSTEM.GET32(packetAddr),-4)) * {0..3};
ASSERT(packetAddr > 0);
IF packetSize < 4 THEN
KernelLog.String("The packet size is wrong::procRcvdPckts"); KernelLog.Ln();
FirewireLowUtil.StopContext(context.ctrlClear);
RETURN
END;
IF (context.prgr.packetOffset + packetSize) > bufSize THEN
packetBytesLeft:= bufSize - context.prgr.packetOffset; i:= 0;
ASSERT(packetBytesLeft <= FirewireLowUtil.BufSize);
WHILE i < packetBytesLeft-1 DO
SYSTEM.PUT32(ConvertToLongint(context.tempBuffer[0])+i,SYSTEM.GET32(packetAddr + i));
INC(i,4)
END;
block.end:= ConvertToLongint(context.prgr.curDesc);
nextDesc:= SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 8)-1;
ASSERT(nextDesc > 0);
bufSize:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(nextDesc))*{0..15});
resCount:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(nextDesc + 12))*{0..15});
packetBytesRight:= bufSize - resCount; i:= 0;
ASSERT(packetAddr > 0);
ASSERT(packetBytesRight <= FirewireLowUtil.BufSize-packetBytesLeft);
WHILE i < packetBytesRight-1 DO
SYSTEM.PUT32(ConvertToLongint(context.tempBuffer[0])+packetBytesLeft+i,SYSTEM.GET32(packetAddr + i));
INC(i,4)
END;
context.prgr.curDesc:= SYSTEM.VAL(SET,nextDesc);
ASSERT(ConvertToLongint(context.prgr.curDesc) > 0);
block.start:= ConvertToLongint(context.prgr.curDesc);
context.prgr.packetOffset:= bufSize-resCount;
ELSE
packetBytesLeft:= bufSize - context.prgr.packetOffset; i:= 0;
ASSERT(packetBytesLeft <= FirewireLowUtil.BufSize);
WHILE i < packetBytesLeft-1 DO
SYSTEM.PUT32(ConvertToLongint(context.tempBuffer[0])+i,SYSTEM.GET32(packetAddr + i));
INC(i,4)
END;
IF resCount = 0 THEN
block.end:= ConvertToLongint(context.prgr.curDesc);
nextDesc:= SYSTEM.GET32(ConvertToLongint(context.prgr.curDesc) + 8)-1;
context.prgr.curDesc:= SYSTEM.VAL(SET,nextDesc);
ASSERT(ConvertToLongint(context.prgr.curDesc) > 0);
block.start:= ConvertToLongint(context.prgr.curDesc);
END;
context.prgr.packetOffset:= bufSize-resCount;
END;
IF (SYSTEM.VAL(LONGINT,tCode) = FirewireLowUtil.PhyARReq) THEN
ELSE
ack:= FirewireLowUtil.ReadReg(context.ctrlSet) * {0..4};
IF ConvertToLongint(ack) = FirewireLowUtil.AckComplete THEN complete:= TRUE
ELSE complete:= FALSE
END;
PacketReceived(context,context.tempBuffer[0], packetSize, complete);
END;
END ProcRcvdPckts;
PROCEDURE FreeDMABuffer(context:Contest);
VAR curDesc: LONGINT; active: LONGINT;
BEGIN
active:= 10;
curDesc:= ConvertToLongint(context.prgr.curDesc);
ASSERT(ConvertToLongint(context.prgr.curDesc) > 0);
context.prgr.SetBranchAddress(curDesc+1,curDesc+8,context.prgr.ptrToBuf);
context.buffers.FreeBuffer(SYSTEM.VAL(SET,SYSTEM.GET32(curDesc + 4)));
IF ~(active IN FirewireLowUtil.ReadReg(context.ctrlSet)) THEN
END;
FirewireLowUtil.WriteReg(context.ctrlSet,{12});
END FreeDMABuffer;
PROCEDURE PacketReceived(context: Contest; bufferAddr:SET; packetSize: LONGINT; complete: BOOLEAN);
VAR tCode: LONGINT;
BEGIN
IF OHCI.inBusReset THEN KernelLog.String("Ignoring packet, because OHCI is in bus reset!"); RETURN END;
tCode:= SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.LSH(SYSTEM.GET32(ConvertToLongint(bufferAddr)),-4))*{0..3});
CASE tCode OF
FirewireLowUtil.NoDataWARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
|FirewireLowUtil.QReadARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
|FirewireLowUtil.BReadARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
|FirewireLowUtil.LockARRes: HandlePacketResponse(context,bufferAddr,packetSize,tCode)
|FirewireLowUtil.QWriteARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
|FirewireLowUtil.BWriteARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
|FirewireLowUtil.NoDataQRARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
|FirewireLowUtil.BReadARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
|FirewireLowUtil.LockARReq: HandleIncomingPacket(bufferAddr,packetSize,tCode,complete)
|FirewireLowUtil.IRCode: KernelLog.String("Received iso packet: NOT YET IMPLEMENTED!");
KernelLog.Ln()
|FirewireLowUtil.CycleStartCode:
ELSE KernelLog.String("Received bad tCode for a packet!"); KernelLog.Ln()
END;
END PacketReceived;
PROCEDURE CreateReplyPacket(VAR p: FirewireLowUtil.OHCIPacket; dataAddr: LONGINT; dataSize: LONGINT);
BEGIN
p:= OHCI.packetFIFO.GetPacket();
p.dataSize:= dataSize;
FirewireLowUtil.ResetPacket(p);
p.type:= FirewireLowUtil.async;
p.state:= FirewireLowUtil.UNUSED;
p.host:= OHCI;
p.nodeID:= SYSTEM.VAL(SET,SYSTEM.LSH(SYSTEM.GET32(dataAddr+4),-16))*{0..5};
p.tLabel:= SYSTEM.VAL(SET,SYSTEM.LSH(SYSTEM.GET32(dataAddr),-10))*{0..5};
p.generation:= FirewireLowUtil.GetGeneration();
p.respExpected:= FALSE;
END CreateReplyPacket;
PROCEDURE WriteToAddress(dataAddr: LONGINT; dataLen: LONGINT; writeAddrLo, writeAddrHi: SET):LONGINT;
VAR i: LONGINT;
BEGIN
i:= 0;
IF writeAddrHi*{0..15} # {} THEN
RETURN FirewireLowUtil.respAddressError
ELSIF ~OHCI.adrCheck.Find(ConvertToLongint(writeAddrLo)) THEN HALT(55);
ELSE
FOR i:= 0 TO dataLen-1 DO
SYSTEM.PUT32(ConvertToLongint(writeAddrLo)+i*4,SYSTEM.GET32(dataAddr+i*4))
END
END;
RETURN FirewireLowUtil.respComplete;
END WriteToAddress;
PROCEDURE ReadFromAddress(VAR bufferAddr: ARRAY OF SET; dataLen: LONGINT; readAddrLo, readAddrHi: SET): LONGINT;
VAR i: LONGINT;
BEGIN
i:= 0;
FOR i:= 0 TO dataLen-1 DO
bufferAddr[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(ConvertToLongint(readAddrLo)+i*4));
END;
RETURN FirewireLowUtil.respComplete;
END ReadFromAddress;
PROCEDURE HandleIncomingPacket(bufferAddr: SET; packetSize, tCode: LONGINT; complete: BOOLEAN);
VAR addrHi,addrLo: SET; rCode,dataLen,addr: LONGINT; packet: FirewireLowUtil.OHCIPacket; respBufferAddr: LONGINT;
respQuadlet: ARRAY 1 OF SET;
BEGIN
addr:= ConvertToLongint(bufferAddr);
CASE tCode OF
FirewireLowUtil.QWriteARReq:
addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
rCode:= WriteToAddress(addr+12,1,addrLo,addrHi);
IF ~complete THEN
CreateReplyPacket(packet,addr,0);
FirewireLowUtil.FillAsyncWriteResp(packet,rCode);
IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
END
END
|FirewireLowUtil.BWriteARReq:
addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
dataLen:= (SYSTEM.LSH(SYSTEM.GET32(addr+12),-16));
rCode:= WriteToAddress(addr+16,(dataLen DIV 4),addrLo,addrHi);
IF ~complete THEN
CreateReplyPacket(packet,addr,0);
FirewireLowUtil.FillAsyncWriteResp(packet,rCode);
IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
END
END
|FirewireLowUtil.NoDataQRARReq:
addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
rCode:= ReadFromAddress(respQuadlet,1,addrLo,addrHi);
CreateReplyPacket(packet,addr,0);
FirewireLowUtil.FillAsyncReadQuadResp(packet,rCode,respBufferAddr);
IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
END
|FirewireLowUtil.BReadARReq:
dataLen:= (SYSTEM.LSH(SYSTEM.GET32(addr+12),-16));
CreateReplyPacket(packet,addr,dataLen);
addrLo:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+8));
addrHi:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+4));
rCode:= ReadFromAddress(packet.data^,(dataLen DIV 4),addrLo,addrHi);
FirewireLowUtil.FillAsyncReadBlockResp(packet,rCode,dataLen);
IF SendPacket1394(OHCI.ATController.GetResContest(),packet) THEN
ELSE KernelLog.String("Response could not be sent"); KernelLog.Ln()
END
|FirewireLowUtil.LockARReq:
ELSE KernelLog.String("This request is not supported!"); KernelLog.Ln();
END;
END HandleIncomingPacket;
PROCEDURE HandlePacketResponse(respContext: Contest; bufferAddr: SET; packetSize, tCode: LONGINT);
VAR oneBack,temp: POINTER TO ListMember; tLabel, nodeID: SET; found, tCodeMatch: BOOLEAN; packet: OHCIPacket;
data: LONGINT; i: LONGINT; context: Contest; n: FirewireLowUtil.FIFONode;
BEGIN
context:= OHCI.ATController.GetReqContest();
found:= FALSE;
oneBack:= context.listAwaiting.head;
temp:= oneBack.next;
nodeID:= SYSTEM.VAL(SET,SYSTEM.LSH(SYSTEM.GET32(ConvertToLongint(bufferAddr)+4),-16))*{0..5};
tLabel:= SYSTEM.VAL(SET,SYSTEM.LSH(SYSTEM.GET32(ConvertToLongint(bufferAddr)),-10))*{0..5};
IF ~context.listAwaiting.GetPacket(packet) THEN
ELSE
KernelLog.String("We have a problem"); KernelLog.Ln()
END;
WHILE (temp # NIL) & ~(found) DO
IF (temp.data.tLabel = tLabel) & (temp.data.nodeID = nodeID) THEN
found:= TRUE; packet:= temp.data;
ELSE oneBack:= temp; temp:= temp.next
END
END;
IF ~found THEN KernelLog.String("This packet was not expected, no tLabel match"); KernelLog.Ln();
RETURN
END;
CASE SYSTEM.VAL(LONGINT,packet.tCode) OF
FirewireLowUtil.QWriteATReq:
IF (tCode = FirewireLowUtil.NoDataWARRes) THEN tCodeMatch:= TRUE END
|FirewireLowUtil.BWriteATReq:
IF (tCode = FirewireLowUtil.NoDataWARRes) THEN tCodeMatch:= TRUE END
|FirewireLowUtil.BReadATReq:
IF (tCode = FirewireLowUtil.BReadARRes) THEN tCodeMatch:= TRUE END
|FirewireLowUtil.NoDataWATReq:
IF (tCode = FirewireLowUtil.QReadARRes) THEN tCodeMatch:= TRUE END
|FirewireLowUtil.LockATReq:
IF (tCode = FirewireLowUtil.LockARRes) THEN tCodeMatch:= TRUE END
END;
IF (~tCodeMatch OR (packet.tLabel # tLabel)) OR (packet.nodeID # nodeID) THEN
IF tCodeMatch THEN
ELSE KernelLog.String("Transaction code didn't match: "); FirewireLowUtil.PrintSet(packet.tCode);
FirewireLowUtil.PrintSet(SYSTEM.VAL(SET,tCode)); KernelLog.Ln()
END;
KernelLog.String("This packet was not expected, tcode mismatch!"); RETURN
END;
IF found THEN
IF oneBack = temp THEN
context.listAwaiting.head:= context.listAwaiting.head.next
ELSE oneBack.next:= temp.next;
IF context.listAwaiting.last = temp THEN
context.listAwaiting.last:= oneBack END;
END;
temp.next:= NIL;
n:= context.listAwaiting.usedList.DequeuedNode(context.listAwaiting.usedQ);
n.pListMember:= temp;
context.listAwaiting.list.Enqueue(context.listAwaiting.q,n);
END;
data:= ConvertToLongint(bufferAddr);
CASE tCode OF
FirewireLowUtil.NoDataWARRes:
packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
|FirewireLowUtil.QReadARRes:
packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
packet.header[3]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 12));
|FirewireLowUtil.BReadARRes:
packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
packet.header[3]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 12));
FOR i:= 0 TO ((packetSize-16) DIV 4)-1 DO
packet.data[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(data+16+i*4))
END
|FirewireLowUtil.LockARRes:
packet.header[0]:= SYSTEM.VAL(SET,SYSTEM.GET32(data));
packet.header[1]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 4));
packet.header[2]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 8));
packet.header[3]:= SYSTEM.VAL(SET,SYSTEM.GET32(data + 12));
IF packetSize-16 > 8 THEN
FOR i:= 0 TO (8 DIV 4)-1 DO
packet.data[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(data+16+i*4))
END
ELSE
FOR i:= 0 TO ((packetSize-16) DIV 4)-1 DO
packet.data[i]:= SYSTEM.VAL(SET,SYSTEM.GET32(data+16+i*4));
END
END
END;
BEGIN{EXCLUSIVE}
packet.state:= FirewireLowUtil.COMPLETE;
END;
packet.pending:= FALSE;
OHCI.labeler.FreeTransLabel(packet.tLabel);
IF packet.dataSize > 0 THEN
respContext.buffers.FreeBuffer(SYSTEM.VAL(SET,SYSTEM.GET32(packet.block.start+36)))
END;
PacketComplete(context,packet);
END HandlePacketResponse;
PROCEDURE PacketComplete(context: Contest; VAR packet: OHCIPacket);
END PacketComplete;
PROCEDURE PacketSent(context:Contest;VAR packet: OHCIPacket; ack: SET);
BEGIN
packet.ack:= ack;
IF packet.respExpected & (packet.ack # {0,4}) THEN
packet.pending:= TRUE; context.listAwaiting.AddPacket(packet)
ELSE packet.pending:= FALSE; packet.state:= FirewireLowUtil.COMPLETE; OHCI.labeler.FreeTransLabel(packet.tLabel);
END;
END PacketSent;
PROCEDURE HandleInterrupt;
VAR status, reg, nodeID: SET; ctx,i: LONGINT; root, error: BOOLEAN;
CONST dead= 11; isValid= 31; id= {0..5}; isRoot= 30;
BEGIN
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{31});
status := FirewireLowUtil.ReadReg(FirewireLowUtil.CIntEvent);
IF reqTxComplete IN status THEN
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATReqContCtrlSet);
IF (dead IN reg) THEN FirewireLowUtil.StopContext(FirewireLowUtil.ATReqContCtrlClear);
ELSE ProcSentPckts(OHCI.ATController.GetReqContest()) END;
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{reqTxComplete});
END;
IF respTxComplete IN status THEN
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATResContCtrlSet);
IF (dead IN reg) THEN FirewireLowUtil.StopContext(FirewireLowUtil.ATResContCtrlClear);
ELSE ProcSentPckts(OHCI.ATController.GetResContest()) END;
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{respTxComplete});
END;
IF ARRQ IN status THEN
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{ARRQ});
END;
IF ARRS IN status THEN
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{ARRS});
END;
IF RQPkt IN status THEN
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARReqContCtrlSet);
IF (dead IN reg) THEN FirewireLowUtil.StopContext(FirewireLowUtil.ARReqContCtrlClear);
ELSE ProcRcvdPckts(OHCI.ARController.GetReqContest()) END;
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{RQPkt});
END;
IF RSPkt IN status THEN
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARResContCtrlSet);
IF (dead IN reg) THEN FirewireLowUtil.StopContext(FirewireLowUtil.ARResContCtrlClear);
ELSE ProcRcvdPckts(OHCI.ARController.GetResContest()) END;
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{RSPkt});
END;
IF isochTx IN status THEN
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochXmitIntEvntSet);
FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntEvntClear,reg);
IsoSchedule(reg);
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{isochTx});
END;
IF isochRx IN status THEN
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochRecvIntEvntSet);
IsoSchedule(reg);
FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntEvntClear,reg);
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{isochRx});
END;
IF postedWriteErr IN status THEN
KernelLog.String("A host bus error occurred"); KernelLog.Ln();
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{postedWriteErr});
END;
IF lockRespErr IN status THEN
KernelLog.String("Host controller attempted to return a lock response without receiving an ack"); KernelLog.Ln();
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{lockRespErr});
END;
IF busReset IN status THEN
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{busReset});
IF ~OHCI.inBusReset THEN
OHCI.inBusReset:= TRUE;
ELSE KernelLog.String("bus Reset Interrupt was thrown while already in progress"); KernelLog.Ln();
END;
END;
IF selfIDComplete2 IN status THEN
END;
IF selfIDComplete IN status THEN
error:= FALSE;
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{selfIDComplete});
IF OHCI.inBusReset THEN
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID);
IF isValid IN reg THEN
IF isRoot IN reg THEN root:= TRUE; OHCI.IsRoot:= TRUE END;
nodeID:= reg*id;
IF CheckSelfIDStream() THEN error:= TRUE END;
ELSE KernelLog.String("Self id is not valid, do not check self id buffer!"); KernelLog.Ln()
END;
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{busReset});
FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{busReset});
FirewireLowUtil.WriteReg(FirewireLowUtil.ARFilterHISet, {0..31});
FirewireLowUtil.WriteReg(FirewireLowUtil.ARFilterLowSet, {0..31});
FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterHiSet, {0..31});
FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterLowSet, {0..31});
FirewireLowUtil.WriteReg(FirewireLowUtil.PhyUpperBound, {16..31});
IF OHCI.inBusReset THEN OHCI.inBusReset:= FALSE;
ELSE KernelLog.String("This should not happen!"); KernelLog.Ln(); END;
IF error THEN FirewireLowUtil.SetPhyControl({8},{6})
ELSE
OHCI.nodeID:= SYSTEM.VAL(LONGINT,FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{0..5});
BuildMaps(); BEGIN {EXCLUSIVE} OHCI.selfIDComplete:= TRUE; END;
END;
ELSE KernelLog.String("SelfID received outside of bus reset"); KernelLog.Ln() END;
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{selfIDComplete});
FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{selfIDComplete});
END;
IF regAccessFail IN status THEN
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{regAccessFail});
KernelLog.String("Open HCI register access failed "); KernelLog.Ln();
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{regAccessFail});
FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{regAccessFail});
END;
IF phy IN status THEN
KernelLog.String("phy requests an interrupt"); KernelLog.Ln();
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{phy});
END;
IF cycleSynch IN status THEN
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleSynch});
END;
IF cycle64Seconds IN status THEN
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycle64Seconds});
END;
IF cycleLost IN status THEN
KernelLog.String("No cyclestart packet is sent/received "); KernelLog.Ln();
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleLost});
END;
IF cycleInconsistent IN status THEN
KernelLog.String("An inconsistent cycle start was received"); KernelLog.Ln();
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleInconsistent});
END;
IF unrecoverableError IN status THEN
KernelLog.String("Host controller encountered an unrecoverable error"); KernelLog.Ln();
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATReqContCtrlSet);
IF dead IN reg THEN KernelLog.String("The asynchronous transmit request context died!"); KernelLog.Ln();
KernelLog.String("With event code: "); reg:= reg*{0..4}; FirewireLowUtil.PrintSet(reg); KernelLog.Ln();
KernelLog.String("The register content is: "); FirewireLowUtil.StopContext(FirewireLowUtil.ATReqContCtrlClear);
FirewireLowUtil.PrintSet(FirewireLowUtil.ReadReg(FirewireLowUtil.ATReqContCtrlSet)); KernelLog.Ln();
END;
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ATResContCtrlSet);
IF dead IN reg THEN KernelLog.String("The asynchronous transmit response context died!"); KernelLog.Ln() END;
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARReqContCtrlSet);
IF dead IN reg THEN KernelLog.String("The asynchronous receive request context died!"); KernelLog.Ln() END;
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.ARResContCtrlSet);
IF dead IN reg THEN KernelLog.String("The asynchronous receive response context died!"); KernelLog.Ln() END;
ctx:= FirewireLowUtil.GetAvailableITCont();
FOR i:= 0 TO ctx-1 DO
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochXmitCntCtrlSet + i*16);
IF dead IN reg THEN KernelLog.String("The isochronous transmit context "); KernelLog.Int(i,2); KernelLog.String(" died!");
KernelLog.Ln()
END
END;
ctx:= FirewireLowUtil.GetAvailableIRCont();
FOR i:= 0 TO ctx-1 DO
reg:= {}; reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochRecvCntCtrlSet + i*32);
IF dead IN reg THEN KernelLog.String("The isochronous receive context "); KernelLog.Int(i,2); KernelLog.String(" died!");
KernelLog.Ln()
END
END;
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{unrecoverableError});
END;
IF cycleTooLong IN status THEN
KernelLog.String("An isochronous cycle lasted longer than the allotted time"); KernelLog.Ln();
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{cycleTooLong});
END;
IF ackTardy IN status THEN
KernelLog.String("HCControl.ackTardyEnable is set to one and other conditions occur"); KernelLog.Ln();
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{ackTardy});
END;
IF softInterrupt IN status THEN
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{softInterrupt});
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{softInterrupt});
FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{softInterrupt});
END;
IF phyRegRcvd IN status THEN
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntMask,{phyRegRcvd});
FirewireLowUtil.WriteReg(FirewireLowUtil.CIntEvent,{phyRegRcvd});
FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{phyRegRcvd});
END;
FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{31});
END HandleInterrupt;
PROCEDURE SendPacket(contest: Contest; VAR packet : OHCIPacket; z: LONGINT);
VAR cycleTimer: SET; desc,descLast: FirewireLowUtil.GeneralDesc; descOMI: FirewireLowUtil.OutputMoreImmediate;
descOL: FirewireLowUtil.OutputLast; descOLI: FirewireLowUtil.OutputLastImmediate; block: FirewireLowUtil.Block;
branchAddressPtr: LONGINT; ptrToBuf: FirewireLowUtil.CharBuffer;
BEGIN
desc.address := {};
desc.branchAddress := {};
IF contest.type = FirewireLowUtil.RES THEN
cycleTimer:= FirewireLowUtil.ReadReg(FirewireLowUtil.isochCycleTimer);
desc.status:= SYSTEM.LSH(cycleTimer*{12..24},-12) +
FirewireLowUtil.ConvertToSet(SYSTEM.LSH(SYSTEM.LSH(ConvertToLongint(cycleTimer),-25)+3,13));
ELSE desc.status:= {};
END;
IF (packet.type = FirewireLowUtil.async) OR (packet.type = FirewireLowUtil.raw) THEN
descOMI:= FirewireLowUtil.GetAOMIDesc();
descOL:= FirewireLowUtil.GetAOLDesc();
descOLI:= FirewireLowUtil.GetAOLIDesc();
IF packet.type = FirewireLowUtil.raw THEN
desc.data[0]:= FirewireLowUtil.ConvertToSet(SYSTEM.LSH(FirewireLowUtil.PhyATReq,4));
desc.data[1]:= packet.header[0];
desc.data[2]:= packet.header[1];
ELSE
desc.data[0]:= SYSTEM.LSH(packet.speed,16) + {23} +
packet.header[0]*{0..15};
IF SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.StreamATReq THEN
desc.data[1]:= packet.header[0] * {16..31}; desc.data[0]:= desc.data[0] - {23}
ELSE
desc.data[1]:= packet.header[1] * {0..15} + packet.header[0] * {16..31};
desc.data[2]:= packet.header[2]; desc.data[3]:= packet.header[3]
END;
END;
IF packet.dataSize > 0 THEN
IF SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.StreamATReq THEN
desc.control:= descOMI.key + {3};
ELSE
desc.control:= descOMI.key + {4}
END;
descLast.control:= descOL.cmd + descOL.i + descOL.b +
FirewireLowUtil.ConvertToSet(packet.dataSize);
ASSERT(packet.dataSize < FirewireLowUtil.BufSize);
descLast.address:= FirewireLowUtil.AllocPacket(packet.data^,packet.dataSize,SYSTEM.ADR(OHCI.tempBuffer[0]));
descLast.branchAddress:= {}; descLast.status:= {};
ELSE
IF packet.type = FirewireLowUtil.raw THEN
desc.control:= descOLI.cmd + descOLI.key + descOLI.b + descOLI.i +
FirewireLowUtil.ConvertToSet(packet.headerSize + 4)
ELSE
desc.control:= descOLI.cmd + descOLI.key + descOLI.b + descOLI.i +
FirewireLowUtil.ConvertToSet(packet.headerSize)
END
END
ELSE
descOMI:= FirewireLowUtil.GetIOMIDesc();
descOL:= FirewireLowUtil.GetIOLDesc();
KernelLog.String("We have an iso packet"); KernelLog.Ln();
desc.data[0]:= packet.header[0]*{0..15} +
SYSTEM.LSH(packet.speed,16);
desc.data[1]:= packet.header[0]*{16..31};
desc.control:= descOMI.key + {3};
descLast.control:= descOL.cmd + descOL.b + descOL.i +
FirewireLowUtil.ConvertToSet(packet.dataSize);
descLast.address:= FirewireLowUtil.AllocPacket(packet.data^,packet.dataSize,SYSTEM.ADR(OHCI.tempBuffer[0]));
descLast.branchAddress:= {}; descLast.status:= {};
END;
block.start:= packet.blockBufferAddr;
ASSERT(block.start > 0);
(* KernelLog.Int(block.start,2); *)
SYSTEM.PUT32(block.start, desc.control);
SYSTEM.PUT32(block.start + 4, desc.address);
SYSTEM.PUT32(block.start + 8, desc.branchAddress);
SYSTEM.PUT32(block.start + 12, desc.status);
SYSTEM.PUT32(block.start + 16, desc.data[0]);
SYSTEM.PUT32(block.start + 20, desc.data[1]);
SYSTEM.PUT32(block.start + 24, desc.data[2]);
SYSTEM.PUT32(block.start + 28, desc.data[3]);
IF packet.dataSize > 0 THEN
SYSTEM.PUT32(block.start + 32, descLast.control);
SYSTEM.PUT32(block.start + 36, descLast.address);
SYSTEM.PUT32(block.start + 40, descLast.branchAddress);
SYSTEM.PUT32(block.start + 44, descLast.status);
branchAddressPtr:= block.start + 40; block.end:= block.start + 32;
ptrToBuf:= packet.ptrToBlckBufAddr;
ELSE
branchAddressPtr:= block.start + 8; block.end:= block.start;
ptrToBuf:= packet.ptrToBlckBufAddr;
END;
contest.prgr.SetBranchAddress(block.start+z,branchAddressPtr,ptrToBuf);
packet.block:= block;
contest.listInserted.AddPacket(packet);
END SendPacket;
PROCEDURE OHCISend(VAR packet: OHCIPacket):BOOLEAN;
VAR contest: FirewireLowUtil.Contest; result: BOOLEAN; i,ms: LONGINT;
BEGIN
IF packet.dataSize > OHCI.MaxPacketSize THEN KernelLog.String("The packet size is too big!"); KernelLog.Ln();
RETURN FALSE;
END;
IF packet.type = FirewireLowUtil.raw THEN contest:= OHCI.ATController.GetReqContest()
ELSIF SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.ITCode THEN OHCI.ITController.ResetIterator();
contest:= OHCI.ITController.GetNextContest()
ELSIF ((SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.NoDataWATRes) OR (SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.QReadATRes)
OR (SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.BReadATRes) OR (SYSTEM.VAL(LONGINT,packet.tCode) = FirewireLowUtil.LockATRes))
THEN contest:= OHCI.ATController.GetResContest()
ELSE contest:= OHCI.ATController.GetReqContest()
END;
contest.listPending.AddPacket(packet);
IF ~FillFifo(contest) THEN result:= TRUE ELSE result:= FALSE END;
i:= 0;
IF packet.respExpected THEN
BEGIN{EXCLUSIVE}
ms:= 5;
Kernel.SetTimer(timer,ms);
Objects.SetTimeout(clock, SELF.HandleTimeout, ms);
timeout:= FALSE;
AWAIT((packet.state = FirewireLowUtil.COMPLETE) OR timeout)
END;
END;
IF packet.state = FirewireLowUtil.COMPLETE THEN
ELSE
END;
RETURN result
END OHCISend;
PROCEDURE FillFifo(contest: FirewireLowUtil.Contest):BOOLEAN;
VAR packet: OHCIPacket; error: BOOLEAN; z: LONGINT; tempAddr: LONGINT;
CONST isRunning= 15; active= 10;
BEGIN
error:= contest.listPending.GetPacket(packet);
IF (error) THEN
RETURN FALSE
END;
IF packet.dataSize > 0 THEN
z:= 3
ELSE z:= 2
END;
WHILE ~error DO
error:= contest.listPending.DelPacket(packet);
SendPacket(contest,packet,z);
error:= contest.listPending.GetPacket(packet);
END;
error:= FALSE;
tempAddr:= SYSTEM.GET32(packet.blockBufferAddr);
IF ~(isRunning IN FirewireLowUtil.ReadReg(contest.ctrlSet)) THEN
FirewireLowUtil.WriteReg(contest.cmdPtr,FirewireLowUtil.ConvertToSet(packet.blockBufferAddr + z));
IF FirewireLowUtil.StartContest(contest) THEN
ELSE KernelLog.String("The context didn't start successfully!"); KernelLog.Ln();
END
ELSE
IF ~(active IN FirewireLowUtil.ReadReg(contest.ctrlSet)) THEN
ELSE
END;
FirewireLowUtil.WriteReg(contest.ctrlSet,{12});
END;
RETURN error;
END FillFifo;
PROCEDURE SendPacket1394(context: Contest;VAR packet: OHCIPacket):BOOLEAN;
CONST queued = 0;
VAR speed: LONGINT;
BEGIN
IF packet.host.inBusReset
OR (packet.generation # SYSTEM.VAL(LONGINT,SYSTEM.LSH(FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount)*{16..23},-16))) THEN
KernelLog.String("Generation mismatch or host in bus reset!"); KernelLog.Ln(); RETURN FALSE
END;
packet.state:= FirewireLowUtil.QUEUED;
IF ( SYSTEM.VAL(LONGINT,packet.nodeID) = packet.host.nodeID ) THEN
KernelLog.String("It's an internal packet!"); KernelLog.Ln();
RETURN FALSE
END;
IF (packet.type = FirewireLowUtil.async) & (packet.nodeID # {0..5}) THEN
speed:= OHCI.SpeedMap[OHCI.nodeID][SYSTEM.VAL(LONGINT,packet.nodeID)];
packet.speed:= FirewireLowUtil.ConvertToSet(speed);
END;
RETURN OHCISend(packet);
END SendPacket1394;
PROCEDURE ConfigRomAlloc;
VAR buffer: FirewireLowUtil.CharBuffer; adr: LONGINT; s: SET;
BEGIN
NEW(buffer, 2048);
adr:= SYSTEM.ADR(buffer[0]);
DEC(adr,adr MOD 1024);
INC(adr,1024);
s:= SYSTEM.VAL(SET,adr);
OHCI.ptrToConfigRomBuf:= buffer;
OHCI.ConfigRomBufferAdr:= s;
END ConfigRomAlloc;
PROCEDURE InitARRDesc;
CONST cmd = {29}; s = {27}; i = {21,20}; b = {19,18}; reqCount = {9}; resCount = {9};
VAR desc: FirewireLowUtil.InputMoreDesc;
BEGIN
desc.cmd := cmd; desc.s := s; desc.b := b;
desc.i := i; desc.reqCount := reqCount; desc.resCount := resCount;
OHCI.IMDesc:= desc;
END InitARRDesc;
PROCEDURE ConfigARR;
VAR reqCont, resCont: FirewireLowUtil.Contest; controller: FirewireLowUtil.ADMAController; size: LONGINT;
BEGIN
OHCI.ARDescNum:= 4;
InitARRDesc();
OHCI.MaxPacketSize:= FirewireLowUtil.GetMaxPcktSize();
size:= 10;
NEW(controller,size,OHCI.ARDescNum);
OHCI.ARController:= controller;
reqCont:= OHCI.ARController.GetReqContest();
reqCont.type:= FirewireLowUtil.REQ;
reqCont.name := "AR request";
reqCont.cmdPtr:= FirewireLowUtil.ARReqComPtr;
reqCont.ctrlSet:= FirewireLowUtil.ARReqContCtrlSet;
reqCont.ctrlClear:= FirewireLowUtil.ARReqContCtrlClear;
reqCont.type:= FirewireLowUtil.RES;
resCont:= OHCI.ARController.GetResContest();
resCont.name:= "AR response";
resCont.cmdPtr:= FirewireLowUtil.ARResComPtr;
resCont.ctrlSet:= FirewireLowUtil.ARResContCtrlSet;
resCont.ctrlClear:= FirewireLowUtil.ARResContCtrlClear;
resCont.prgr.SetBufferAddr(FirewireLowUtil.AllocARResBuf(resCont.prgr.ptrToBuf));
reqCont.prgr.SetBufferAddr(FirewireLowUtil.AllocARReqBuf(reqCont.prgr.ptrToBuf));
FirewireLowUtil.AllocPcktBuf(1,reqCont.tempBuffer,reqCont.ptrToTmpBuf);
FirewireLowUtil.AllocPcktBuf(1,resCont.tempBuffer,resCont.ptrToTmpBuf);
END ConfigARR;
PROCEDURE ConfigATR;
VAR reqCont, resCont: FirewireLowUtil.Contest; controller: FirewireLowUtil.ADMAController; size : LONGINT;
BEGIN
OHCI.ATDescNum:= 32;
size:= 10;
NEW(controller,size,OHCI.ATDescNum);
OHCI.ATController:= controller;
reqCont:= OHCI.ATController.GetReqContest();
reqCont.type:= FirewireLowUtil.REQ;
reqCont.name:= "AT request";
reqCont.cmdPtr:= FirewireLowUtil.ATReqComPtr;
reqCont.ctrlSet:= FirewireLowUtil.ATReqContCtrlSet;
reqCont.ctrlClear:= FirewireLowUtil.ATReqContCtrlClear;
resCont:= OHCI.ATController.GetResContest();
resCont.type:= FirewireLowUtil.RES;
resCont.name:= "AT response";
resCont.cmdPtr:= FirewireLowUtil.ATResComPtr;
resCont.ctrlSet:= FirewireLowUtil.ATResContCtrlSet;
resCont.ctrlClear:= FirewireLowUtil.ATResContCtrlClear;
resCont.prgr.SetBufferAddr(FirewireLowUtil.AllocATResBuf(resCont.prgr.ptrToBuf));
reqCont.prgr.SetBufferAddr(FirewireLowUtil.AllocATReqBuf(reqCont.prgr.ptrToBuf));
END ConfigATR;
PROCEDURE ConfigIR;
VAR contest: FirewireLowUtil.IRContest; controller: FirewireLowUtil.IRDMAController; size, avIRCont, i: LONGINT;
str: ARRAY 5 OF CHAR;
BEGIN
avIRCont:= FirewireLowUtil.GetAvailableIRCont();
size:= 10; i:= 0;
OHCI.IRDescNum:= 16;
NEW(controller,avIRCont,size,OHCI.IRDescNum);
OHCI.IRController:= controller;
WHILE controller.hasNext DO contest:= controller.GetNextContest();
contest.type:= FirewireLowUtil.ISO;
contest.name:= "IR "; Strings.IntToStr(i,str); Strings.Append(str,contest.name);
contest.cmdPtr:= FirewireLowUtil.IRComPtr+(32*i);
contest.ctrlSet:= FirewireLowUtil.isochRecvCntCtrlSet+(32*i);
contest.ctrlClear:= FirewireLowUtil.isochRecvCntCtrlClear+(32*i);
contest.match:= FirewireLowUtil.isochRecvContMatch+(32*i);
contest.prgr.SetBufferAddr(FirewireLowUtil.AllocIRBuf(contest.prgr.ptrToBuf,OHCI.IRDescNum));
INC(i);
END;
END ConfigIR;
PROCEDURE ConfigIT;
VAR contest: FirewireLowUtil.Contest; controller: FirewireLowUtil.ITDMAController; size, avITCont, i: LONGINT;
str: ARRAY 5 OF CHAR;
BEGIN
avITCont:= FirewireLowUtil.GetAvailableITCont();
size:= 10; i:= 0;
OHCI.ITDescNum:= 16;
NEW(controller,avITCont,size,OHCI.ITDescNum);
OHCI.ITController:= controller;
WHILE controller.hasNext DO contest:= controller.GetNextContest();
contest.type:= FirewireLowUtil.ISO;
contest.name:= "IT "; Strings.IntToStr(i,str); Strings.Append(str,contest.name);
contest.cmdPtr:= FirewireLowUtil.ITComPtr+(16*i);
contest.ctrlSet:= FirewireLowUtil.isochXmitCntCtrlSet+(16*i);
contest.ctrlClear:= FirewireLowUtil.isochXmitCntCtrlClear+(16*i);
contest.prgr.SetBufferAddr(FirewireLowUtil.AllocITBuf(contest.prgr.ptrToBuf,OHCI.ITDescNum));
INC(i);
END;
END ConfigIT;
PROCEDURE InitAsyncRecvCont;
VAR i: LONGINT; desc: FirewireLowUtil.InputMoreDesc; s, Z, branchAddress, dataAddress:SET;
quadlet1, quadlet2, quadlet3, quadlet4, reqCount: SET; reqCntst, resCntst: FirewireLowUtil.Contest; block: FirewireLowUtil.Block;
branchAddressPtr: LONGINT;
BEGIN
desc:= OHCI.IMDesc;
reqCntst:= OHCI.ARController.GetReqContest();
resCntst:= OHCI.ARController.GetResContest();
FirewireLowUtil.StopContext(reqCntst.ctrlClear);
FirewireLowUtil.StopContext(resCntst.ctrlClear);
block.descNum:= OHCI.ARDescNum;
block.start:= reqCntst.prgr.bufferAddr;
FOR i:= 0 TO OHCI.ARDescNum-1 DO
s:= desc.cmd + desc.s + desc.b;
reqCount:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.BufSize);
dataAddress:= reqCntst.buffers.GetBuffer();
quadlet1:= s + reqCount; quadlet2:= dataAddress; quadlet4:= reqCount;
IF i+1 = OHCI.ARDescNum THEN
quadlet3:= SYSTEM.VAL(SET,block.start) + {0}; block.end:= reqCntst.prgr.bufferAddr + i*16;
branchAddressPtr:= reqCntst.prgr.bufferAddr + i*16+8;
reqCntst.prgr.nextAddr:= reqCntst.prgr.bufferAddr + i*16+16;
ELSE Z:= {0}; branchAddress:= FirewireLowUtil.ConvertToSet(reqCntst.prgr.bufferAddr + (i+1)*16);
quadlet3:= branchAddress + Z;
END;
SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16, quadlet1);
SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16+4, quadlet2);
SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16+8, quadlet3);
SYSTEM.PUT32(reqCntst.prgr.bufferAddr + i*16+12, quadlet4);
END;
reqCntst.prgr.blockBuffer.Append(block);
block.descNum:= OHCI.ARDescNum;
block.start:= resCntst.prgr.bufferAddr;
FOR i:= 0 TO OHCI.ARDescNum-1 DO
s:= desc.cmd + desc.s + desc.b;
reqCount:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.BufSize);
dataAddress:= resCntst.buffers.GetBuffer();
quadlet1:= s + reqCount; quadlet2:= dataAddress; quadlet4:= reqCount;
IF i+1 = OHCI.ARDescNum THEN
quadlet3:= SYSTEM.VAL(SET,block.start)+{0}; block.end:= resCntst.prgr.bufferAddr + i*16;
branchAddressPtr:= resCntst.prgr.bufferAddr + i*16+8;
resCntst.prgr.nextAddr:= resCntst.prgr.bufferAddr + i*16+16;
ELSE Z:= {0}; branchAddress:= FirewireLowUtil.ConvertToSet(resCntst.prgr.bufferAddr + (i+1)*16);
quadlet3:= branchAddress + Z;
END;
SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16, quadlet1);
SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16+4, quadlet2);
SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16+8, quadlet3);
SYSTEM.PUT32(resCntst.prgr.bufferAddr + i*16+12, quadlet4);
END;
resCntst.prgr.blockBuffer.Append(block);
s:= FirewireLowUtil.ConvertToSet(reqCntst.prgr.bufferAddr) + {0};
SYSTEM.PUT32(base + reqCntst.cmdPtr, s);
ASSERT(FirewireLowUtil.StartContest(reqCntst));
s:= FirewireLowUtil.ConvertToSet(resCntst.prgr.bufferAddr) + {0};
SYSTEM.PUT32(base + resCntst.cmdPtr, s);
ASSERT(FirewireLowUtil.StartContest(resCntst));
END InitAsyncRecvCont;
PROCEDURE InitIsochRecvCont;
VAR i: LONGINT; desc: FirewireLowUtil.InputMoreDesc; s, Z, branchAddress, dataAddress:SET;
quadlet1, quadlet2, quadlet3, quadlet4, reqCount: SET; contest: FirewireLowUtil.IRContest; block: FirewireLowUtil.Block;
branchAddressPtr: LONGINT;
BEGIN
OHCI.IRController.ResetIterator();
IF OHCI.IRController.hasNext THEN contest:= OHCI.IRController.GetNextContest() END;
desc:= OHCI.IMDesc;
FirewireLowUtil.StopContext(contest.ctrlClear);
block.descNum:= OHCI.IRDescNum;
block.start:= contest.prgr.bufferAddr;
FOR i:= 0 TO OHCI.IRDescNum-1 DO
s:= desc.cmd + desc.s + desc.b + desc.i;
reqCount:= FirewireLowUtil.ConvertToSet(FirewireLowUtil.BufSize);
dataAddress:= contest.buffers.GetBuffer();
quadlet1:= s + reqCount; quadlet2:= dataAddress; quadlet4:= reqCount;
IF i+1 = OHCI.IRDescNum THEN
quadlet3:= SYSTEM.VAL(SET,block.start)+{0}; block.end:= contest.prgr.bufferAddr + i*16;
branchAddressPtr:= contest.prgr.bufferAddr + i*16+8;
contest.prgr.nextAddr:= contest.prgr.bufferAddr + i*16+16;
ELSE Z:= {0}; branchAddress:= FirewireLowUtil.ConvertToSet(contest.prgr.bufferAddr + (i+1)*16);
quadlet3:= branchAddress + Z;
END;
SYSTEM.PUT32(contest.prgr.bufferAddr + i*16, quadlet1);
SYSTEM.PUT32(contest.prgr.bufferAddr + i*16+4, quadlet2);
SYSTEM.PUT32(contest.prgr.bufferAddr + i*16+8, quadlet3);
SYSTEM.PUT32(contest.prgr.bufferAddr + i*16+12, quadlet4);
END;
contest.prgr.blockBuffer.Append(block);
s:= FirewireLowUtil.ConvertToSet(contest.prgr.bufferAddr) + {0};
SYSTEM.PUT32(base + contest.cmdPtr, s);
ASSERT(FirewireLowUtil.StartContest(contest));
END InitIsochRecvCont;
PROCEDURE InitIsochXmitCont;
VAR i: LONGINT; contest: FirewireLowUtil.Contest;
BEGIN
OHCI.ITController.ResetIterator();
WHILE OHCI.ITController.hasNext DO contest:= OHCI.ITController.GetNextContest();
FirewireLowUtil.StopContext(contest.ctrlClear + i*16);
END
END InitIsochXmitCont;
PROCEDURE InitAsyncXmitCont;
VAR reqCont, resCont: FirewireLowUtil.Contest;
BEGIN
reqCont:= OHCI.ATController.GetReqContest(); resCont:= OHCI.ATController.GetResContest();
FirewireLowUtil.StopContext(reqCont.ctrlClear);
FirewireLowUtil.StopContext(resCont.ctrlClear);
END InitAsyncXmitCont;
PROCEDURE ControlStatus;
END ControlStatus;
PROCEDURE FindNodeInfo;
CONST csrDone= 31;
VAR reg: SET; done: BOOLEAN;
BEGIN
FirewireLowUtil.WriteReg(FirewireLowUtil.CSRData,{0..5});
FirewireLowUtil.WriteReg(FirewireLowUtil.CSRCompare,{0..5});
FirewireLowUtil.WriteReg(FirewireLowUtil.CSRControl,{});
reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRControl);
done:= FALSE;
WHILE ~done DO
IF csrDone IN reg THEN done:= TRUE ELSE
reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRControl)
END
END;
reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRData);
END FindNodeInfo;
PROCEDURE IsoSchedule(reg: SET);
VAR controller: FirewireLowUtil.IRDMAController; i: LONGINT;
BEGIN
FOR i:= 0 TO controller.avIRCont-1 DO
IF i IN reg THEN ProcRcvdPckts(controller.GetContest(i)) END
END;
END IsoSchedule;
PROCEDURE DevInit;
VAR reg: SET;
BEGIN
NEW(t);
ConfigRomAlloc();
SelfIDAlloc();
FirewireLowUtil.CheckSelfIDCount();
ConfigARR();
ConfigATR();
FirewireLowUtil.SoftReset();
reg := {};
INCL(reg, LPS);
FirewireLowUtil.SetHCControl(reg);
t.Sleep(50);
FirewireLowUtil.CheckAvailableIR();
FirewireLowUtil.CheckAvailableIT();
ConfigIR();
ConfigIT();
END DevInit;
PROCEDURE InitOHCI;
VAR i: LONGINT;
BEGIN
FOR i:= 0 TO 62 DO
OHCI.Nodes[i]:= NIL
END;
OHCI.selfIDComplete:= FALSE;
NEW(OHCI.adrCheck);
NEW(t);NEW(clock);
NEW(OHCI.packetFIFO,10);
OHCI.MaxPacketSize:= FirewireLowUtil.GetMaxPcktSize();
NEW(OHCI.tempBuffer,OHCI.MaxPacketSize);
END InitOHCI;
PROCEDURE&Init*(base,irq:LONGINT);
CONST irmcCmcIsc = {31,30,29}; cycClkAcc = {16..23}; pmcBmc = {28,27}; postedWriteEnable= {18};
programPhyEnable= 23; aPhyEnhanceEnable= 22; rcvPhyPkt = 10; postedWriteErr = 8;
VAR reg:SET;
BEGIN
SELF.base:=base;
SELF.irq:=irq;
DevInit();
InitOHCI();
IF(irq >= 1) & (irq <= 15) THEN Objects.InstallHandler(SELF.HandleInterrupt, Machine.IRQ0+irq)
END;
reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.BusOptions);
reg:= reg + irmcCmcIsc;
reg:= reg - cycClkAcc;
reg:= reg - pmcBmc;
FirewireLowUtil.WriteReg(FirewireLowUtil.BusOptions,reg);
FirewireLowUtil.WriteReg(FirewireLowUtil.NodeID,busNumber);
FirewireLowUtil.SetHCControl(postedWriteEnable);
FirewireLowUtil.WriteReg(FirewireLowUtil.CLinkControl,{0..31});
reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.HCControl);
IF programPhyEnable IN reg THEN OHCI.ExstRegMap:= TRUE;
IF ~(aPhyEnhanceEnable IN reg) THEN FirewireLowUtil.SetHCControl({aPhyEnhanceEnable}) END
ELSE OHCI.ExstRegMap:= FALSE
END; reg:= {};
FirewireLowUtil.WriteReg(FirewireLowUtil.LinkControl,{10,20,21});
IF OHCI.ExstRegMap THEN FirewireLowUtil.SetPhyControl({10},{6}) END;
FirewireLowUtil.ClearIntEventAll();
FirewireLowUtil.ClearIntMaskAll();
FirewireLowUtil.WriteReg(FirewireLowUtil.SelfIDBuffer,OHCI.SelfIDBufferAdr);
FirewireLowUtil.WriteReg(FirewireLowUtil.LinkControl,{rcvSelfID});
FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvCntCtrlSet,{28,30,31});
FirewireLowUtil.SetIsochRecvContMatch({28..31});
FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntEvntClear,{0..31});
FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntMaskClear,{0..31});
FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntEvntClear,{0..31});
FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntMaskClear,{0..31});
FirewireLowUtil.WriteReg(FirewireLowUtil.IRmultiChanMaskHiClear,{0..31});
FirewireLowUtil.WriteReg(FirewireLowUtil.IRmultiChanMaskLoClear,{0..31});
InitAsyncRecvCont();
InitAsyncXmitCont();
InitIsochRecvCont();
InitIsochXmitCont();
FirewireLowUtil.WriteReg(FirewireLowUtil.isochRecvIntMaskSet,{0});
FirewireLowUtil.WriteReg(FirewireLowUtil.isochXmitIntMaskSet,{0});
FirewireLowUtil.WriteReg(FirewireLowUtil.ARFilterHISet,{31});
reg:= FirewireLowUtil.MaxPhysRespRetries + FirewireLowUtil.MaxATReqRetries
+ FirewireLowUtil.MaxATRespRetries;
FirewireLowUtil.WriteReg(FirewireLowUtil.ATRetries, reg);
FirewireLowUtil.WriteReg(FirewireLowUtil.PhyUpperBound,{16..31});
reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.PhyUpperBound);
IF reg = {16..31} THEN
ELSE
END;
FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterHiSet,{0..30});
FirewireLowUtil.WriteReg(FirewireLowUtil.PRFilterLowSet,{0..31});
FirewireLowUtil.WriteReg(FirewireLowUtil.HCControl,{30});
FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,{31});
reg:= {};
INCL(reg,unrecoverableError);
INCL(reg,busReset);
INCL(reg,regAccessFail);
INCL(reg,selfIDComplete);
INCL(reg,RSPkt);
INCL(reg,RQPkt);
INCL(reg,respTxComplete);
INCL(reg,reqTxComplete);
INCL(reg,isochRx);
INCL(reg,isochTx);
INCL(reg,cycleInconsistent);
INCL(reg,postedWriteErr);
FirewireLowUtil.WriteReg(FirewireLowUtil.IntMask,reg);
FirewireLowUtil.CheckIntMask();
FirewireLowUtil.CheckIntEvent();
NEW(OHCI.labeler,63);
OHCI.inBusReset:= FALSE;
reg:= {};
INCL(reg, LinkEnable);
FirewireLowUtil.SetHCControl(reg);
FirewireLowUtil.SetPhyControl({8},{6});
BEGIN {EXCLUSIVE}
AWAIT(OHCI.selfIDComplete)
END;
ScanNodes();
KernelLog.String("Finished OHCI initialization"); KernelLog.Ln();
END Init;
PROCEDURE CheckBusManager;
CONST isRoot= 30;
VAR selfIDBuf: SET; reg: SET;nodeID,data: SET;countReg,selfIDSize,IRMID: SET; i,j,size: LONGINT;
BEGIN
nodeID:= FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{0..5};
OHCI.nodeID:= ConvertToLongint(nodeID);
reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.NodeID)*{30};
IF isRoot IN reg THEN OHCI.IsRoot:= TRUE; OHCI.IsIRM:= TRUE;
FirewireLowUtil.WriteReg(FirewireLowUtil.CSRData,nodeID);
FirewireLowUtil.WriteReg(FirewireLowUtil.CSRCompare,{0..5});
FirewireLowUtil.WriteReg(FirewireLowUtil.CSRControl,{});
IRMID:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRData);
IF IRMID = {0..5} THEN
OHCI.IsBM:= TRUE; IRMID:= nodeID ELSE OHCI.IsBM:= FALSE
END;
ELSE
selfIDBuf:= OHCI.SelfIDBufferAdr;
countReg:= FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount);
selfIDSize := SYSTEM.LSH(countReg,-2);
selfIDSize := selfIDSize*{0..8};
size := ConvertToLongint(selfIDSize);
j:= 4;
OHCI.IsIRM:= TRUE;
FOR i:= 0 TO size-2 DO
data := SYSTEM.VAL(SET, SYSTEM.GET32(ConvertToLongint(selfIDBuf)+j)); INC(j,8);
IF (11 IN data) & (22 IN data) THEN
data:= SYSTEM.LSH(data,-24)*{0..5};
IF OHCI.nodeID > ConvertToLongint(data) THEN
OHCI.IsIRM:= FALSE
END
END
END;
IF OHCI.IsIRM THEN
FirewireLowUtil.WriteReg(FirewireLowUtil.CSRData,nodeID);
FirewireLowUtil.WriteReg(FirewireLowUtil.CSRCompare,{0..5});
FirewireLowUtil.WriteReg(FirewireLowUtil.CSRControl,{});
IRMID:= FirewireLowUtil.ReadReg(FirewireLowUtil.CSRData);
IF IRMID = {0..5} THEN
OHCI.IsBM:= TRUE; IRMID:= nodeID ELSE OHCI.IsBM:= FALSE
END
ELSE
KernelLog.Ln();
END;
OHCI.IsRoot:= FALSE; OHCI.IsIRM:= FALSE END;
END CheckBusManager;
PROCEDURE ScanUnitDirectory(node: FirewireLowUtil.Node);
END ScanUnitDirectory;
PROCEDURE ProcessUnitDirectory(VAR ud: FirewireLowUtil.UnitDirectory; node: FirewireLowUtil.Node; addrLow, addrHigh: SET; VAR id: LONGINT);
VAR length,addr,code,value,i: LONGINT; udTemp: FirewireLowUtil.UnitDirectory; context: Contest; buffer: SET;
BEGIN
context:= OHCI.ATController.GetReqContest();
addr:= SYSTEM.VAL(LONGINT,addrLow);
IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
KernelLog.String("There was an error::ProcessUnitDirectory"); KernelLog.Ln(); RETURN
END;
length:= SYSTEM.VAL(LONGINT,SYSTEM.LSH(buffer,-16));
NEW(ud,length);
ud.addrLow:= addrLow;
ud.addrHigh:= addrHigh;
INC(id); ud.ID:= id;
INC(addr,4);
addrLow:= SYSTEM.VAL(SET,addr);
i:= 0;
WHILE length > 0 DO
IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
END;
ud.udEntries[i]:= buffer;
code:= SYSTEM.VAL(LONGINT,SYSTEM.LSH(buffer,-24));
value:= SYSTEM.VAL(LONGINT,buffer*{0..23});
CASE code OF
FirewireLowUtil.ConfigRomVendorID: ud.vendorID:= value;
|FirewireLowUtil.ConfigRomModelID: ud.modelID:= value;
|FirewireLowUtil.ConfigRomSpecifierID: ud.specifierID:= value;
|FirewireLowUtil.ConfigRomUnitSWVersion: ud.version:= value;
|FirewireLowUtil.ConfigRomDescriptorLeaf:
|FirewireLowUtil.ConfigRomDescriptorDirectory:
|FirewireLowUtil.ConfigRomLogicalUnitDirectory:
ud.hasLogicalUnitDir:= TRUE;
ProcessUnitDirectory(udTemp,node,SYSTEM.VAL(SET,addr+value*4),addrHigh,id);
IF udTemp.vendorID = 0 THEN udTemp.vendorID:= ud.vendorID END;
IF udTemp.modelID = 0 THEN udTemp.modelID:= ud.modelID END;
IF udTemp.specifierID = 0 THEN udTemp.specifierID:= ud.specifierID END;
IF udTemp.version = 0 THEN udTemp.version:= ud.version END;
ud.luns[udTemp.ID]:= udTemp;
ELSE
END;
DEC(length); INC(addr,4); addrLow:= SYSTEM.VAL(SET,addr); INC(i);
END;
END ProcessUnitDirectory;
PROCEDURE ProcessRootDirectory(node: FirewireLowUtil.Node);
VAR context: Contest; buffer, addrLow, addrHigh: SET; code, value, addr, busInfoLength, rootDirLength, id: LONGINT;
ud: FirewireLowUtil.UnitDirectory;
BEGIN
id:= -1;
addrHigh:= FirewireLowUtil.CSRBaseHigh;
addrLow:= FirewireLowUtil.CSRBaseLow;
addrLow:= addrLow + FirewireLowUtil.CSRConfigRom;
addr:= SYSTEM.VAL(LONGINT,addrLow);
context:= OHCI.ATController.GetReqContest();
IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
END;
busInfoLength:= SYSTEM.VAL(LONGINT,SYSTEM.LSH(buffer,-24));
addr:= addr + 4 + busInfoLength*4;
addrLow:= SYSTEM.VAL(SET,addr);
IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
END;
rootDirLength:= SYSTEM.VAL(LONGINT,SYSTEM.LSH(buffer,-16));
INC(addr,4);
addrLow:= SYSTEM.VAL(SET,addr);
WHILE rootDirLength > 0 DO
IF ~Read1394(context,OHCI,node.phyID,node.generation,addrLow,addrHigh,buffer,4) THEN
KernelLog.String("There was an error::ProcessRootDirectory"); KernelLog.Ln(); RETURN
END;
code:= SYSTEM.VAL(LONGINT,SYSTEM.LSH(buffer,-24));
value:= SYSTEM.VAL(LONGINT,buffer*{0..23});
CASE code OF
FirewireLowUtil.ConfigRomVendorID: node.vendorID:= value;
|FirewireLowUtil.ConfigRomNodeCapabilities: node.capabilities:= SYSTEM.VAL(SET,value);
|FirewireLowUtil.ConfigRomUnitDirectory:
ProcessUnitDirectory(ud,node,SYSTEM.VAL(SET,addr + value*4),addrHigh,id);
node.uds[ud.ID]:= ud;
ELSE
END;
DEC(rootDirLength); INC(addr,4); addrLow:= SYSTEM.VAL(SET,addr);
END;
END ProcessRootDirectory;
PROCEDURE ScanRootDirectory;
END ScanRootDirectory;
PROCEDURE ScanEachNode(physicalID: SET; generation: LONGINT);
VAR buffer: ARRAY 5 OF SET; bufferLength,i: LONGINT;
node: FirewireLowUtil.Node; found: BOOLEAN; guid: FirewireLowUtil.GUID;
BEGIN
bufferLength:= 5;
IF ReadBusInfoBlock(OHCI,physicalID,generation,buffer,bufferLength) THEN RETURN END;
IF (buffer[1] # SYSTEM.VAL(SET,FirewireLowUtil.BusIDNumber)) THEN
KernelLog.String("This device an invalid bus id number::ScanEachNode!"); KernelLog.Ln()
END;
guid.high:= buffer[3]; guid.low:= buffer[4];
i:= 0; found:= FALSE;
WHILE (OHCI.Nodes[i] # NIL) & ~found DO
node:= OHCI.Nodes[i];
IF (node.guid.low = guid.low) & (node.guid.high = guid.high) THEN
found:= TRUE
ELSE INC(i)
END
END;
IF found THEN
node.Update(buffer[2],physicalID,generation);
ELSE
NEW(node,guid,buffer[2],physicalID,generation); OHCI.Nodes[i]:= node;
END;
END ScanEachNode;
PROCEDURE ScanNodes*;
VAR i,generation: LONGINT; sid: FirewireLowUtil.SelfID; node: FirewireLowUtil.Node;
BEGIN
WHILE OHCI.TopologyMap[i] # NIL DO
sid:= OHCI.TopologyMap[i];
IF ~sid.extended & (sid.linkActive={0}) THEN
IF sid.physicalID # SYSTEM.VAL(SET,OHCI.nodeID) THEN
generation:= FirewireLowUtil.GetGeneration();
ScanEachNode(sid.physicalID,generation)
END
END;
INC(i)
END;
i:= 0;
WHILE OHCI.Nodes[i] # NIL DO
node:= OHCI.Nodes[i];
IF node.probe THEN ProcessRootDirectory(node) END; INC(i);
END;
END ScanNodes;
PROCEDURE BuildMaps;
VAR size,i,j,addr: LONGINT; quad,reg: SET; sid: FirewireLowUtil.SelfID; esid: FirewireLowUtil.ExtSelfID;
speed, children: ARRAY 64 OF LONGINT; c: LONGINT;
BEGIN
OHCI.numOfNodes:= 0;
addr:= SYSTEM.VAL(LONGINT,OHCI.SelfIDBufferAdr) + 4;
reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.SelfIDCount);
size:= SYSTEM.VAL(LONGINT,SYSTEM.LSH(reg * {2..10},-2));
size:= ((size-1) DIV 2)-1;
FOR i:= 0 TO 64-1 DO children[i]:= 0 END;
FOR i:= 0 TO size DO
quad:= SYSTEM.VAL(SET,SYSTEM.GET32(addr+(i*8)));
IF 23 IN quad THEN NEW(esid,quad); OHCI.TopologyMap[i]:= esid;
ELSE
NEW(sid,quad); OHCI.TopologyMap[i]:= sid; INC(OHCI.numOfNodes);
END;
END;
OHCI.TopologyMap[i]:= NIL;
i:= 0;
WHILE OHCI.TopologyMap[i] # NIL DO
sid:= OHCI.TopologyMap[i]; c:= 0;
IF sid.extended THEN
esid:= sid (FirewireLowUtil.ExtSelfID);
IF (esid.pa = {0,1}) THEN INC(children[i]) END;
IF (esid.pb = {0,1}) THEN INC(children[i]) END;
IF (esid.pc = {0,1}) THEN INC(children[i]) END;
IF (esid.pd = {0,1}) THEN INC(children[i]) END;
IF (esid.pe = {0,1}) THEN INC(children[i]) END;
IF (esid.pf = {0,1}) THEN INC(children[i]) END;
IF (esid.pg = {0,1}) THEN INC(children[i]) END;
IF (esid.ph = {0,1}) THEN INC(children[i]) END;
ELSE
IF (sid.p0 = {0,1}) THEN INC(children[i]) END;
IF (sid.p1 = {0,1}) THEN INC(children[i]) END;
IF (sid.p2 = {0,1}) THEN INC(children[i]) END;
speed[i]:= SYSTEM.VAL(LONGINT,sid.sp);
END;
IF ~(0 IN sid.m) THEN INC(i) END;
END;
FOR i:= 0 TO OHCI.numOfNodes-1 DO
OHCI.SpeedMap[i][i]:= speed[i];
END;
i:= OHCI.numOfNodes-2;
WHILE i >= 0 DO
c:= children[i];
FOR j:=1 TO c DO INC(children[i],children[i+j]);
IF speed[i] < speed[i+j] THEN speed[i+j]:= speed[i] END;
END;
DEC(i);
END;
i:= 0; j:= 0;
FOR i:= 0 TO OHCI.numOfNodes-1 DO
FOR j:= 0 TO OHCI.numOfNodes-1 DO
IF i # j THEN
OHCI.SpeedMap[i][j]:= speed[j]
END
END
END;
END BuildMaps;
PROCEDURE Lock1394(context: Contest; ohci: FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT; addrLow, addrHigh: SET; extCode: LONGINT;
VAR data: SET; VAR arg: SET):BOOLEAN;
VAR packet: OHCIPacket; success: BOOLEAN;
BEGIN
success:= FALSE;
packet:= FirewireLowUtil.MakeLockPacket(ohci,nodeID,addrLow,addrHigh,extCode,data,arg);
packet.generation:= generation;
IF (~SendPacket1394(context,packet)) THEN
KernelLog.String("Something went wrong:: Lock1394"); KernelLog.Ln();
OHCI.labeler.FreeTransLabel(packet.tLabel);
RETURN success
ELSE KernelLog.String("Everything ok::Lock1394"); KernelLog.Ln();
END;
success:= FirewireLowUtil.TestIfSuccess(packet);
IF success THEN data:= packet.data[0] END;
OHCI.labeler.FreeTransLabel(packet.tLabel);
OHCI.packetFIFO.ReleasePacket(packet);
RETURN success
END Lock1394;
PROCEDURE Write1394*(context: Contest; ohci: FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT; VAR buffer: SET; addrLow, addrHigh: SET;
length: LONGINT):BOOLEAN;
VAR packet: OHCIPacket; success: BOOLEAN; tries: LONGINT;
BEGIN
success:= FALSE; tries:= 0;
IF length = 0 THEN RETURN success END;
packet:= FirewireLowUtil.MakeWritePacket(ohci,nodeID,addrLow,addrHigh,buffer,length);
packet.generation:= generation;
WHILE (~success) & (tries < 4) DO
IF (SendPacket1394(context,packet)) THEN success:= TRUE
ELSE INC(tries); KernelLog.String("Something went wrong:: Write1394"); KernelLog.Ln();
END
END;
IF ~success THEN
KernelLog.String("Something went wrong:: Write1394"); KernelLog.Ln();
OHCI.labeler.FreeTransLabel(packet.tLabel);
RETURN success
END;
success:= FirewireLowUtil.TestIfSuccess(packet);
IF ~success THEN KernelLog.String("Not successfull:: Read1394"); KernelLog.Ln(); END;
OHCI.labeler.FreeTransLabel(packet.tLabel);
OHCI.packetFIFO.ReleasePacket(packet);
RETURN success
END Write1394;
PROCEDURE Read1394*(context: Contest; ohci: FirewireLowUtil.OHCIDesc; nodeID: SET;generation: LONGINT; addrLow,addrHigh:SET;
VAR buffer: SET; length: LONGINT):BOOLEAN;
VAR packet: OHCIPacket; success: BOOLEAN; tries,i: LONGINT;
BEGIN
success:= FALSE; tries:= 0;
IF length = 0 THEN RETURN success END;
packet:= FirewireLowUtil.MakeReadPacket(ohci,nodeID,addrLow,addrHigh,length);
packet.generation:= generation;
WHILE (~success) & (tries < 4) DO
IF (SendPacket1394(context,packet)) THEN success:= TRUE
ELSE INC(tries)
END
END;
IF ~success THEN
KernelLog.String("Something went wrong:: Read1394"); KernelLog.Ln();
OHCI.labeler.FreeTransLabel(packet.tLabel);
RETURN success
END;
success:= FirewireLowUtil.TestIfSuccess(packet);
IF success THEN
IF length = 4 THEN
buffer:= packet.header[3];
ELSE
FOR i:= 0 TO (length DIV 4)-1 DO
SYSTEM.PUT32(ConvertToLongint(buffer) + i*4,packet.data[i])
END
END
ELSE KernelLog.String("Packet was not successfull!"); KernelLog.Ln();
END;
OHCI.labeler.FreeTransLabel(packet.tLabel);
OHCI.packetFIFO.ReleasePacket(packet);
RETURN success
END Read1394;
PROCEDURE NodeManagerReadQ(context: Contest; host:FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT;
addrLow,addrHigh: SET; VAR quad: SET):BOOLEAN;
VAR success: BOOLEAN; i: LONGINT;
BEGIN
success:= FALSE; i:= 0;
WHILE ~success & (i < 4) DO
success:= Read1394(context,host,nodeID,generation,addrLow,addrHigh,quad,4);
IF ~success THEN INC(i) END;
END;
IF i>=1 THEN KernelLog.String("Something went wrong::NodeManagerReadQ"); KernelLog.Ln()
ELSE
END;
RETURN success
END NodeManagerReadQ;
PROCEDURE ReadBusInfoBlock(host: FirewireLowUtil.OHCIDesc; nodeID: SET; generation: LONGINT; VAR buffer: ARRAY OF SET;
bufferLength: LONGINT):BOOLEAN;
VAR addrLow,addrHigh, base: SET; i, headerSize: LONGINT; vendorID: LONGINT; context: Contest;
BEGIN
addrHigh:= FirewireLowUtil.CSRBaseHigh;
addrLow:= FirewireLowUtil.CSRBaseLow + FirewireLowUtil.CSRConfigRom;
buffer[0]:= {};
context:= OHCI.ATController.GetReqContest();
WHILE (buffer[0] = {}) & (i<1) DO
IF ~NodeManagerReadQ(context,host,nodeID,generation,addrLow,addrHigh,buffer[0]) THEN
KernelLog.String("Quadlet read error!"); KernelLog.Ln(); INC(i) END;
END;
IF i>=1 THEN KernelLog.String("Error: DEVICE was not ready::ReadBusInfoBlock!");KernelLog.Ln();
RETURN TRUE
END;
headerSize:= SYSTEM.VAL(LONGINT,SYSTEM.LSH(buffer[0],-24));
addrLow:= SYSTEM.VAL(SET,SYSTEM.VAL(LONGINT,addrLow)+4);
IF headerSize = 1 THEN
vendorID:= SYSTEM.VAL(LONGINT,buffer[0]*{0..23});
RETURN FALSE
END;
IF headerSize < 4 THEN
KernelLog.String("Non standard rom format, cannot parse!"); KernelLog.Ln(); RETURN TRUE
END;
FOR i:= 1 TO bufferLength-1 DO
IF ~NodeManagerReadQ(context,host,nodeID,generation,addrLow,addrHigh,buffer[i]) THEN
KernelLog.String("Quadlet read error!"); KernelLog.Ln(); RETURN TRUE
END;
addrLow:= base + SYSTEM.VAL(SET,SYSTEM.VAL(LONGINT,addrLow)+4);
END;
vendorID:= SYSTEM.VAL(LONGINT,SYSTEM.LSH(buffer[3],-8));
RETURN FALSE;
END ReadBusInfoBlock;
PROCEDURE PrintOHCIInfo;
VAR reg: SET; val: LONGINT;
BEGIN
reg:= FirewireLowUtil.ReadReg(FirewireLowUtil.Version);
KernelLog.String("Printing the OHCI information:"); KernelLog.Ln();
val:= SYSTEM.LSH(ConvertToLongint(reg*{16..23}),-16);
KernelLog.String("OHCI version: "); KernelLog.Int(val,2); KernelLog.Ln();
val:= ConvertToLongint(reg*{0..7});
KernelLog.String("OHCI revision: "); KernelLog.Int(val,2); KernelLog.Ln();
IF 24 IN reg THEN KernelLog.String("The OHCI has an GUIDROM"); KernelLog.Ln(); END;
KernelLog.String("The OHCI is on interrupt: "); KernelLog.Int(irq,2); KernelLog.Ln();
KernelLog.String("The max packet size is: "); KernelLog.Int(OHCI.MaxPacketSize,2); KernelLog.Ln();
IF OHCI.ExstRegMap THEN
KernelLog.String("The OHCI has an exstended register map conform to 1394a."); KernelLog.Ln();
ELSE KernelLog.String("The OHCI has no exstended register map."); KernelLog.Ln();
END;
IF OHCI.IsRoot THEN
KernelLog.String("The OHCI is root."); KernelLog.Ln();
ELSE KernelLog.String("The OHCI is not root."); KernelLog.Ln()
END;
IF OHCI.IsIRM THEN
KernelLog.String("The OHCI is isochronous resource manager"); KernelLog.Ln();
ELSE KernelLog.String("The OHCI is not isochronous resource manager"); KernelLog.Ln()
END;
IF OHCI.IsBM THEN
KernelLog.String("The OHCI is bus manager"); KernelLog.Ln();
ELSE KernelLog.String("The OHCI is not bus manager"); KernelLog.Ln()
END
END PrintOHCIInfo;
PROCEDURE TestAccess(name:ARRAY OF CHAR);
VAR reg:SET;
BEGIN
reg := FirewireLowUtil.ReadReg(FirewireLowUtil.IntEvent);
IF(18 IN reg) THEN KernelLog.String("RegAccess ");KernelLog.String(name);KernelLog.String(" failed");KernelLog.Ln;
ELSE KernelLog.String("RegAccess ");KernelLog.String(name);KernelLog.String(" successfull");KernelLog.Ln;
END
END TestAccess;
PROCEDURE Cleanup;
BEGIN
Objects.RemoveHandler(HandleInterrupt,Machine.IRQ0+irq);
END Cleanup;
END Controller;
VAR c*:Controller;
PROCEDURE ScanRomOfNodes*;
VAR j,i:LONGINT; node: FirewireLowUtil.Node;
BEGIN
c.ScanNodes();
i:= 0; j:= 0;
WHILE c.OHCI.Nodes[i] # NIL DO
node:= c.OHCI.Nodes[i];
KernelLog.String("Printing the guid: "); KernelLog.Ln();
KernelLog.String("Printing the unit directories if there are any"); KernelLog.Ln();
WHILE node.uds[j] # NIL DO
KernelLog.String("Printing the specifier id: "); KernelLog.Int(node.uds[j].specifierID,2); KernelLog.Ln();
INC(j);
END;
INC(i);
END;
END ScanRomOfNodes;
PROCEDURE SendPingPacket*;
VAR context: Contest;set0,set1,set2,set3,set4,set5,set6,set7: SET;
dataSize: LONGINT; packet: OHCIPacket; block: FirewireLowUtil.Block;
BEGIN
context:= c.OHCI.ATController.GetReqContest();
set0:= {28} + {25} + {23} + {20,21} + {18,19} + {2,3};
set1:= {};
set2:= {};
set3:= {};
set4:= {5,6,7};
set5:= {};
set6:= -set5;
set7:= {};
packet.type:= FirewireLowUtil.async;
dataSize:= 0;
block.start:= context.prgr.bufferAddr;
block.end:= block.start;
SYSTEM.PUT32(context.prgr.bufferAddr,set0);
SYSTEM.PUT32(context.prgr.bufferAddr+4,set1);
SYSTEM.PUT32(context.prgr.bufferAddr+8,set2);
SYSTEM.PUT32(context.prgr.bufferAddr+12,set3);
SYSTEM.PUT32(context.prgr.bufferAddr+16,set4);
SYSTEM.PUT32(context.prgr.bufferAddr+20,set5);
SYSTEM.PUT32(context.prgr.bufferAddr+24,set6);
SYSTEM.PUT32(context.prgr.bufferAddr+28,set7);
packet.block:= block;
FirewireLowUtil.WriteReg(context.cmdPtr,FirewireLowUtil.ConvertToSet(context.prgr.bufferAddr+2));
FirewireLowUtil.WriteReg(context.ctrlSet,{15});
context.listInserted.AddPacket(packet);
END SendPingPacket;
PROCEDURE SendReadPacket*;
VAR context: Contest; set0, set1, set2, set3, set4, set5, set6, set7: SET;
dataSize: LONGINT; packet: OHCIPacket; block: FirewireLowUtil.Block;
BEGIN
context:= c.OHCI.ATController.GetReqContest();
set0:= {28} + {25} + {20,21} + {18,19} + {2,3};
set1:= {};
set2:= {};
set3:= {};
set4:= {8} + {6};
set5:= {22..31} + {0..15};
set6:= {28..31} + {2,3,4,9};
set7:= {};
NEW(packet,16,0);
packet.type:= FirewireLowUtil.async;
packet.tLabel:= {}; packet.tCode:= {2};
dataSize:= 0;
block.start:= context.prgr.bufferAddr;
block.end:= block.start;
packet.header[0]:= set4;
packet.header[1]:= set5;
packet.header[2]:= set6;
packet.header[3]:= set7;
packet.name:= "vito";
SYSTEM.PUT32(context.prgr.bufferAddr,set0);
SYSTEM.PUT32(context.prgr.bufferAddr+4,set1);
SYSTEM.PUT32(context.prgr.bufferAddr+8,set2);
SYSTEM.PUT32(context.prgr.bufferAddr+12,set3);
SYSTEM.PUT32(context.prgr.bufferAddr+16,set4);
SYSTEM.PUT32(context.prgr.bufferAddr+20,set5);
SYSTEM.PUT32(context.prgr.bufferAddr+24,set6);
SYSTEM.PUT32(context.prgr.bufferAddr+28,set7);
packet.block:= block;
FirewireLowUtil.WriteReg(context.cmdPtr,FirewireLowUtil.ConvertToSet(context.prgr.bufferAddr+2));
context.listInserted.AddPacket(packet);
context.listAwaiting.AddPacket(packet);
IF ~context.listAwaiting.GetPacket(packet) THEN
KernelLog.String("Printing packet name: "); KernelLog.String(packet.name); KernelLog.Ln()
ELSE
KernelLog.String("We have a problem"); KernelLog.Ln()
END;
FirewireLowUtil.WriteReg(context.ctrlSet,{15});
END SendReadPacket;
PROCEDURE SendLockPacket*;
VAR nodeID: SET; context: Contest; generation: LONGINT; addrLow, addrHigh: SET; extCode: LONGINT; data, arg: SET;
BEGIN
extCode:= 2H;
addrLow:= FirewireLowUtil.CSRBaseLow; addrHigh:= FirewireLowUtil.CSRBaseHigh;
addrLow:= addrLow + {4,5,9};
context:= c.OHCI.ATController.GetReqContest();
nodeID:= {};
generation:= FirewireLowUtil.GetGeneration();
data:= {0..31}; arg:= {};
IF c.Lock1394(context,c.OHCI,nodeID,generation,addrLow,addrHigh,extCode,data,arg) THEN
KernelLog.String("First read was successfull::SendLockPacket"); KernelLog.Ln();
KernelLog.String("Printing old value: "); FirewireLowUtil.PrintSet(data); KernelLog.Ln()
ELSE
KernelLog.String("Something went wrong::SendLockPacket"); KernelLog.Ln();
END;
END SendLockPacket;
PROCEDURE SendWritePacket*;
VAR nodeID: SET; context: Contest; generation: LONGINT; addrLow, addrHigh: SET;
buffer: ARRAY 1 OF SET;
BEGIN
addrLow:= FirewireLowUtil.CSRBaseLow; addrHigh:= FirewireLowUtil.CSRBaseHigh;
addrLow:= addrLow + {4,5,9};
context:= c.OHCI.ATController.GetReqContest();
nodeID:= {};
buffer[0]:= {0..31};
generation:= FirewireLowUtil.GetGeneration();
IF c.Write1394(context,c.OHCI,nodeID,generation,buffer[0],addrLow,addrHigh,4) THEN
KernelLog.String("Write was successfull::SendWritePacket"); KernelLog.Ln();
ELSE
KernelLog.String("Something went wrong::SendLockPacket"); KernelLog.Ln();
END;
END SendWritePacket;
PROCEDURE Test1394*;
VAR ohci: FirewireLowUtil.OHCIDesc; generation: LONGINT; sid: FirewireLowUtil.SelfID;
buffer: ARRAY 4 OF SET; i: LONGINT;
BEGIN
ohci:= c.OHCI; generation:= FirewireLowUtil.GetGeneration(); i:= 0;
WHILE ohci.TopologyMap[i] # NIL DO
IF ~(ohci.TopologyMap[i] IS FirewireLowUtil.ExtSelfID) &
(SYSTEM.VAL(LONGINT,ohci.TopologyMap[i].physicalID) # c.OHCI.nodeID) THEN
sid:= ohci.TopologyMap[i];
IF c.ReadBusInfoBlock(ohci,sid.physicalID,generation,buffer,4) THEN
KernelLog.String("There was a problem reading the bus info block::Test1394!"); KernelLog.Ln()
END
END;
INC(i);
END;
END Test1394;
PROCEDURE ScanPCI(vendor,device: LONGINT);
VAR index, bus, dev, fct,res,base,irq:LONGINT;
BEGIN
index := 0;
WHILE(PCI.FindPCIDevice(device, vendor, index, bus, dev, fct) = PCI.Done)
DO
res := PCI.ReadConfigDword(bus,dev,fct,PCI.Adr0Reg,base);
ASSERT(res = PCI.Done);
ASSERT(~ODD(base));
DEC(base, base MOD 16);
Machine.MapPhysical(base,800H,SYSTEM.VAL(SYSTEM.ADDRESS,base));
res := PCI.ReadConfigByte(bus,dev,fct,PCI.IntlReg,irq);
ASSERT(res = PCI.Done);
INC(index);
FirewireLowUtil.SetBase(base);
NEW(c,base,irq);
END;
END ScanPCI;
PROCEDURE Install*;
END Install;
PROCEDURE Cleanup;
BEGIN
c.Cleanup();
END Cleanup;
PROCEDURE Init;
BEGIN
ScanPCI(1106H,3044H);
END Init;
BEGIN
Modules.InstallTermHandler(Cleanup);
Init
END FirewireLow.
System.Free FirewireLow~
Builder.Compile \s *
Aos.Call FirewireLow.Install ~
Aos.Call FirewireLowUtil.PrintSelfIDCount ~
Aos.Call FirewireLow.TestReset ~
System.