PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
sbp2_driver.c
1#include <intrman.h>
2#include <thbase.h>
3#include <thevent.h>
4#include <loadcore.h>
5#include <stdio.h>
6#include <sysclib.h>
7#include <sysmem.h>
8
9// #define DEBUG
10
11#include "iLinkman.h"
12#include "sbp2_disk.h"
13#include "scsi.h"
14#include "mass_debug.h"
15#include "usbhd_common.h"
16
17#define MAX_DEVICES 5
18static struct SBP2Device SBP2Devices[MAX_DEVICES];
19
20/* Thread creation data. */
21static iop_thread_t threadData = {
22 TH_C, /* attr */
23 0, /* option */
24 NULL, /* thread */
25 0x420, /* stacksize */
26 0x30 /* priority */
27};
28
29// static unsigned long int iLinkBufferOffset, iLinkTransferSize;
30static int sbp2_event_flag;
31
32static void ieee1394_callback(int reason, unsigned long int offset, unsigned long int size);
33static void iLinkIntrCBHandlingThread(void *arg);
34static int ieee1394_SendManagementORB(int mode, struct SBP2Device *dev);
35static int ieee1394_InitializeFetchAgent(struct SBP2Device *dev);
36static inline int ieee1394_Sync_withTimeout(u32 n500mSecUnits);
37
38static volatile union
39{
40 struct sbp2_status status;
41 unsigned char buffer[32]; /* Maximum 32 bytes. */
42} statusFIFO;
43
44static void ieee1394_callback(int reason, unsigned long int offset, unsigned long int size)
45{
46 (void)offset;
47 (void)size;
48
49#if 0
50 iLinkBufferOffset = offset;
51 iLinkTransferSize = size;
52
53 if (reason == iLink_CB_WRITE_REQUEST) {
54 u32 statusFIFO_result;
55
56 // XPRINTF("Write request: Offset: 0x%08lx; size: 0x%08lx.\n", iLinkBufferOffset, iLinkTransferSize);
57
58 if (iLinkBufferOffset == (u32)&statusFIFO) { /* Check to be sure that we don't signal ieee1394_Sync() too early; Some transactions are transactions involving multiple ORBs. */
59 statusFIFO_result = statusFIFO.status.status;
60 if (RESP_SRC(statusFIFO_result) != 0)
61 SetEventFlag(sbp2_event_flag, WRITE_REQ_INCOMING); /* Signal ieee1394_Sync() only after the last ORB was read. */
62 }
63 } else
64#endif
65 if (reason == iLink_CB_BUS_RESET) {
66 SetEventFlag(sbp2_event_flag, BUS_RESET_COMPLETE);
67 }
68#if 0
69 else {
70 // XPRINTF("Read request: Offset: 0x%08lx; size: 0x%08lx;\n", iLinkBufferOffset, iLinkTransferSize);
71 }
72#endif
73}
74
75/* Event flag creation data. */
76static iop_event_t evfp = {
77 2, /* evfp.attr=EA_MULTI */
78 0, /* evfp.option */
79 0 /* evfp.bits */
80};
81
82int iLinkIntrCBThreadID;
83
84void init_ieee1394DiskDriver(void)
85{
86 int i;
87
88 for (i = 0; i < MAX_DEVICES; i++) {
89 SBP2Devices[i].IsConnected = 0;
90 SBP2Devices[i].nodeID = 0;
91 SBP2Devices[i].trContext = (-1);
92 }
93
94 sbp2_event_flag = CreateEventFlag(&evfp);
95
96 XPRINTF("Starting threads..\n");
97
98 threadData.thread = &iLinkIntrCBHandlingThread;
99 iLinkIntrCBThreadID = CreateThread(&threadData);
100 StartThread(iLinkIntrCBThreadID, NULL);
101
102 iLinkSetTrCallbackHandler(&ieee1394_callback);
103
104 XPRINTF("Threads created and started.\n");
105
106 iLinkEnableSBus();
107}
108
109static int initConfigureSBP2Device(struct SBP2Device *dev)
110{
111 unsigned char retries;
112
113 retries = 10;
114 do {
115 if (ieee1394_SendManagementORB(SBP2_LOGIN_REQUEST, dev) < 0) {
116 XPRINTF("Error logging into the SBP-2 device.\n");
117 retries--;
118 } else
119 break;
120 } while (retries > 0);
121 if (retries == 0) {
122 XPRINTF("Failed to log into the SBP-2 device.\n");
123 return -1;
124 }
125
126 if (ieee1394_InitializeFetchAgent(dev) < 0) {
127 XPRINTF("Error initializing the SBP-2 device's Fetch Agent.\n");
128 return -2;
129 }
130
131 if (ConfigureSBP2Device(dev) < 0)
132 return -3;
133
134 XPRINTF("Completed device initialization.\n");
135
136/****** !!!FOR TESTING ONLY!!! ******/
137#if 0
138 iop_sys_clock_t lTime;
139 u32 lSecStart, lUSecStart;
140 u32 lSecEnd, lUSecEnd, nbytes, i, rounds;
141 void *buffer;
142 int result;
143
144 nbytes = 1048576;
145 rounds = 64;
146 if ((buffer = malloc(nbytes)) == NULL)
147 printf("Unable to allocate memory. :(\n");
148 printf("Read test: %p.\n", buffer);
149 printf("Start reading data...\n");
150
151 GetSystemTime(&lTime);
152 SysClock2USec(&lTime, &lSecStart, &lUSecStart);
153
154 for (i = 0; i < rounds; i++) {
155 if ((result = scsiReadSector(dev, 16, buffer, nbytes / 512)) != 0) {
156 printf("Sector read error %d.\n", result);
157 break;
158 }
159 }
160 free(buffer);
161
162 GetSystemTime(&lTime);
163 SysClock2USec(&lTime, &lSecEnd, &lUSecEnd);
164
165 printf("Completed.\n");
166
167 printf("Done: %lu %lu/%lu %lu\n", lSecStart, lUSecStart, lSecEnd, lUSecEnd);
168 printf("KB: %lu, time: %lu, Approximate KB/s: %lu", (nbytes * rounds / 1024), (lSecEnd - lSecStart), (nbytes * rounds / 1024) / (lSecEnd - lSecStart));
169 /****** !!!FOR TESTING ONLY!!! ******/
170#endif
171
172 return 0;
173}
174
175static inline int initSBP2Disk(struct SBP2Device *dev)
176{
177 void *managementAgentAddr = NULL;
178 unsigned int ConfigurationROMOffset, DirectorySize, i, LeafData, UnitDirectoryOffset;
179 int result;
180
181 UnitDirectoryOffset = 0;
182
183 /* !! NOTE !! sce1394CrRead() reads data starting from the start of the target device's configuration ROM (0x400),
184 and the offset and data to be read is specified in quadlets (Groups of 4 bytes)!!!!! */
185
186 XPRINTF("Reading configuration ROM for the unit directory offset of node 0x%08x\n", dev->nodeID);
187
188 /* Offset in quadlets: 0x14 / 4 = 5 */
189 ConfigurationROMOffset = 5;
190
191 if ((result = iLinkReadCROM(dev->nodeID, ConfigurationROMOffset, 1, &LeafData)) < 0) {
192 XPRINTF("Error reading the configuration ROM. Error %d.\n", result);
193 return (result);
194 }
195
196 ConfigurationROMOffset++;
197
198 /* Get the Unit Directory's offset from the root directory. */
199 DirectorySize = LeafData >> 16;
200 for (i = 0; i < DirectorySize; i++) {
201 if ((result = iLinkReadCROM(dev->nodeID, ConfigurationROMOffset, 1, &LeafData)) < 0) {
202 XPRINTF("Error reading the configuration ROM. Error %d.\n", result);
203 return (result);
204 }
205
206 if ((LeafData >> 24) == IEEE1394_CROM_UNIT_DIRECTORY) {
207 UnitDirectoryOffset = ConfigurationROMOffset + (LeafData & 0x00FFFFFF);
208 break;
209 }
210
211 ConfigurationROMOffset++;
212 }
213 if (i == DirectorySize)
214 return -1;
215
216 if ((result = iLinkReadCROM(dev->nodeID, UnitDirectoryOffset, 1, &LeafData)) < 0) {
217 XPRINTF("Error reading the configuration ROM. Error %d.\n", result);
218 return (result);
219 }
220
221 DirectorySize = LeafData >> 16;
222 for (i = 0; i < DirectorySize; i++) {
223 /* Get the offset in the configuration ROM of the unit record. */
224 if ((result = iLinkReadCROM(dev->nodeID, UnitDirectoryOffset + 1 + i, 1, &LeafData)) < 0) {
225 XPRINTF("Error reading the configuration ROM. Error %d.\n", result);
226 return (result);
227 }
228
229 switch (LeafData >> 24) {
230 /* Now get the address of the Management Agent CSR. */
231 case IEEE1394_CROM_CSR_OFFSET:
232 managementAgentAddr = (void *)(LeafData & 0x00FFFFFF); /* Mask off the bits that represent the Management Agent key. */
233 XPRINTF("managementAgentAddr=0x%08lx.\n", (u32)managementAgentAddr * 4);
234
235 dev->ManagementAgent_low = (u32)managementAgentAddr * 4 + 0xf0000000;
236 dev->ManagementAgent_high = 0x0000ffff;
237 break;
238 case IEEE1394_CROM_UNIT_CHARA:
239 dev->mgt_ORB_timeout = (LeafData & 0x0000FF00) >> 8;
240 dev->ORB_size = LeafData & 0x000000FF;
241 XPRINTF("mgt_ORB_timeout=%u; ORB_size=%u.\n", dev->mgt_ORB_timeout, dev->ORB_size);
242 break;
243 case IEEE1394_CROM_LOGICAL_UNIT_NUM:
244 dev->LUN = LeafData & 0x0000FFFF;
245 XPRINTF("LUN=0x%08x.\n", dev->LUN);
246 break;
247 }
248 }
249
250 return 1;
251}
252
253/* Hardware event handling threads. */
254static void iLinkIntrCBHandlingThread(void *arg)
255{
256 int nNodes, i, targetDeviceID, nodeID, result;
257 static const unsigned char PayloadSizeLookupTable[] = {
258 7, /* S100; 2^(7+2)=512 */
259 8, /* S200; 2^(8+2)=1024 */
260 9, /* S400; 2^(9+2)=2048 */
261 };
262
263 (void)arg;
264
265 while (1) {
266 WaitEventFlag(sbp2_event_flag, BUS_RESET_COMPLETE, WEF_AND | WEF_CLEAR, NULL);
267
268 /* Disconnect all currently connected nodes. */
269 for (i = 0; i < MAX_DEVICES; i++) {
270 if (SBP2Devices[i].trContext >= 0) {
271 releaseSBP2Device(&SBP2Devices[i]);
272
273 iLinkTrFree(SBP2Devices[i].trContext);
274 SBP2Devices[i].trContext = -1;
275 }
276 }
277
278 if ((nNodes = iLinkGetNodeCount()) < 0) {
279 XPRINTF("Critical error: Failure getting the number of nodes!\n"); /* Error. */
280 }
281
282 XPRINTF("BUS RESET DETECTED. Nodes: %d\n", nNodes);
283 XPRINTF("Local Node: 0x%08x.\n", iLinkGetLocalNodeID());
284
285 // DelayThread(500000); /* Give the devices on the bus some time to initialize themselves (The SBP-2 standard states that a maximum of 5 seconds may be given). */
286
287 targetDeviceID = 0;
288
289 for (i = 0; i < nNodes; i++) {
290 if (targetDeviceID >= MAX_DEVICES) {
291 XPRINTF("Warning! There are more devices that what can be connected to.\n");
292 break;
293 }
294
295 XPRINTF("Attempting to initialize unit %d...\n", i);
296
297 /* 16-bit node ID = BUS NUMBER (Upper 10 bits) followed by the NODE ID (Lower 6 bits). */
298 if ((nodeID = iLinkFindUnit(i, 0x0609e, 0x010483)) < 0) {
299 XPRINTF("Error: Unit %d is not a valid SBP-2 device. Code: %d.\n", i, nodeID);
300 continue;
301 }
302
303 XPRINTF("Detected SBP-2 device.\n");
304
305 SBP2Devices[targetDeviceID].InitiatorNodeID = iLinkGetLocalNodeID();
306
307 XPRINTF("Local Node: 0x%08x.\n", SBP2Devices[targetDeviceID].InitiatorNodeID);
308
309#if 0
310 if (SBP2Devices[targetDeviceID].IsConnected) { /* Already connected to the device. */
311 if (SBP2Devices[targetDeviceID].nodeID == nodeID) { /* Make sure that we're attempting to re-connect to the same device. */
312 if (ieee1394_SendManagementORB(SBP2_RECONNECT_REQUEST, &SBP2Devices[i]) < 0) {
313 XPRINTF("Error reconnecting to the SBP-2 device %u.\n", nodeID);
314 } else {
315 XPRINTF("Successfully reconnected to SBP-2 device %u.", nodeID);
316 targetDeviceID++;
317 continue;
318 }
319 } else
320 SBP2Devices[targetDeviceID].IsConnected = 0;
321 }
322#endif
323
324 SBP2Devices[targetDeviceID].IsConnected = 0;
325
326 /* Attempt a login into the device. */
327 SBP2Devices[targetDeviceID].nodeID = nodeID;
328 if ((result = initSBP2Disk(&SBP2Devices[targetDeviceID])) < 0) {
329 XPRINTF("Error initializing the device. Code: %d.\n", result);
330 continue;
331 }
332
333 SBP2Devices[targetDeviceID].trContext = iLinkTrAlloc(nodeID, iLinkGetNodeMaxSpeed(nodeID));
334
335 if (SBP2Devices[targetDeviceID].trContext >= 0) {
336 XPRINTF("Connected device as node 0x%08x.\n", SBP2Devices[targetDeviceID].nodeID);
337 XPRINTF("Generation number: %d.\n", iLinkGetGenerationNumber());
338
339 SBP2Devices[targetDeviceID].speed = iLinkGetNodeTrSpeed(SBP2Devices[targetDeviceID].trContext);
340 XPRINTF("Current speed: %d.\n", SBP2Devices[targetDeviceID].speed);
341
342 SBP2Devices[targetDeviceID].max_payload = PayloadSizeLookupTable[SBP2Devices[targetDeviceID].speed];
343
344 if (initConfigureSBP2Device(&SBP2Devices[targetDeviceID]) >= 0) {
345 SBP2Devices[targetDeviceID].IsConnected = 1;
346 targetDeviceID++;
347 }
348 } else {
349 XPRINTF("Error allocating a transaction.\n");
350 }
351 }
352
353 for (; targetDeviceID < MAX_DEVICES; targetDeviceID++)
354 SBP2Devices[targetDeviceID].IsConnected = 0; /* Mark the unused device slots as being unused. */
355 }
356}
357
358static void ieee1394_ResetFetchAgent(struct SBP2Device *dev)
359{
360 unsigned long int dummy;
361 int result;
362
363 /* Reset the Fetch Agent. */
364 if ((result = iLinkTrWrite(dev->trContext, dev->CommandBlockAgent_high, dev->CommandBlockAgent_low + 0x04, &dummy, 4)) < 0) {
365 XPRINTF("Error writing to the Fetch Agent's AGENT_RESET register @ 0x%08lx %08lx. Code: %d.\n", dev->CommandBlockAgent_high, dev->CommandBlockAgent_low + 0x04, result);
366 }
367}
368
369static int ieee1394_GetFetchAgentState(struct SBP2Device *dev)
370{
371 unsigned long int FetchAgentState;
372 int result;
373
374 if ((result = iLinkTrRead(dev->trContext, dev->CommandBlockAgent_high, dev->CommandBlockAgent_low, &FetchAgentState, 4)) < 0) {
375 XPRINTF("Error reading the Fetch Agent's AGENT_STATE register @ 0x%08lx %08lx. Code: %d.\n", dev->CommandBlockAgent_high, dev->CommandBlockAgent_low, result);
376 return -1;
377 } else {
378 FetchAgentState = BSWAP32(FetchAgentState);
379 XPRINTF("Fetch Agent state: %lu.\n", FetchAgentState);
380 return FetchAgentState;
381 }
382}
383
384static int ieee1394_InitializeFetchAgent(struct SBP2Device *dev)
385{
386 int result, retries;
387 void *dummy_ORB;
388 struct sbp2_pointer address;
389
390 XPRINTF("Initializing fetch agent...");
391
392 dummy_ORB = malloc(dev->ORB_size * 4);
393 memset(dummy_ORB, 0, dev->ORB_size * 4);
394
395 ieee1394_ResetFetchAgent(dev);
396
397 /* Write the address of the dummy ORB to the fetch agent's ORB_POINTER register. */
398 address.low = (u32)dummy_ORB;
399 address.NodeID = dev->InitiatorNodeID;
400 address.high = 0;
401
402 ((struct sbp2_ORB_pointer *)dummy_ORB)->reserved = NULL_POINTER;
403 ((struct sbp2_ORB_pointer *)dummy_ORB)->high = ((struct sbp2_ORB_pointer *)dummy_ORB)->low = 0;
404 ((struct management_ORB *)dummy_ORB)->flags = (u32)(ORB_NOTIFY | ORB_REQUEST_FORMAT(3));
405
406 retries = 0;
407 while ((result = iLinkTrWrite(dev->trContext, dev->CommandBlockAgent_high, dev->CommandBlockAgent_low + 0x08, &address, 8)) < 0) {
408 XPRINTF("Error writing to the Fetch Agent's ORB_POINTER register @ 0x%08lx %08lx. Code: %d.\n", dev->CommandBlockAgent_high, dev->CommandBlockAgent_low + 0x08, result);
409 ieee1394_ResetFetchAgent(dev);
410
411 retries++;
412 if (retries > 3)
413 return (-1);
414 }
415
416 result = ieee1394_Sync();
417 ieee1394_GetFetchAgentState(dev);
418
419 free(dummy_ORB);
420
421 XPRINTF("done!\n");
422
423 return 1;
424}
425
426static int ieee1394_SendManagementORB(int mode, struct SBP2Device *dev)
427{
428 int result;
429 struct sbp2_pointer address;
430
431 struct sbp2_login_response login_result;
432 struct management_ORB new_management_ORB;
433
434 memset((void *)&statusFIFO, 0, sizeof(statusFIFO));
435 memset(&login_result, 0, sizeof(struct sbp2_login_response));
436 memset(&new_management_ORB, 0, sizeof(struct management_ORB));
437
438 new_management_ORB.status_FIFO.low = (u32)&statusFIFO;
439 new_management_ORB.flags = (u32)(ORB_NOTIFY | ORB_REQUEST_FORMAT(0) | MANAGEMENT_ORB_FUNCTION(mode));
440
441 switch (mode) {
442 case SBP2_LOGIN_REQUEST: /* Login. */
443 /* The reconnect timeout is now set to 0, since the mechanism that determines whether the initiator was already logged into the target or not was not accurate. */
444 new_management_ORB.flags |= (u32)(MANAGEMENT_ORB_RECONNECT(0) | MANAGEMENT_ORB_EXCLUSIVE(1) | MANAGEMENT_ORB_LUN(dev->LUN));
445
446 new_management_ORB.login.response.low = (u32)&login_result;
447 new_management_ORB.length = (MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(struct sbp2_login_response)) | MANAGEMENT_ORB_PASSWORD_LENGTH(0));
448 break;
449#if 0
450 case SBP2_RECONNECT_REQUEST: /* Reconnect. */
451 new_management_ORB.flags |= (u32)(MANAGEMENT_ORB_RECONNECT(4) | MANAGEMENT_ORB_LOGINID(dev->loginID)); /* loginID was stored as a big endian number, so it has to be converted into little endian first. :( */
452 break;
453#endif
454 default:
455 XPRINTF("Warning! Unsupported management ORB type!\n");
456 }
457
458 address.NodeID = dev->InitiatorNodeID;
459 address.high = 0;
460 address.low = (u32)&new_management_ORB;
461
462 XPRINTF("Management ORB: %p. size=%d.\n", &new_management_ORB, sizeof(struct management_ORB));
463 XPRINTF("Address pointer: %p\n", &address);
464
465 if ((result = iLinkTrWrite(dev->trContext, dev->ManagementAgent_high, dev->ManagementAgent_low, &address, 8)) < 0) { /* Write the Login ORB address to the target's Management Agent CSR. */
466 XPRINTF("Error writing to the Management Agent CSR @ 0x%08lx %08lx. Code: %d.\n", dev->ManagementAgent_high, dev->ManagementAgent_low, result);
467 return (result);
468 }
469
470 XPRINTF("Waiting for ILINK...\n");
471
472 result = ieee1394_Sync_withTimeout(dev->mgt_ORB_timeout);
473
474 XPRINTF("statusFIFO= %p; [0]=%u.\n", &statusFIFO, statusFIFO.buffer[0]);
475 if (result >= 0) {
476 switch (mode) {
477 case SBP2_LOGIN_REQUEST: /* Login. */
478 XPRINTF("Done. command_block_agent= 0x%08x %08lx.\n", login_result.command_block_agent.high, login_result.command_block_agent.low);
479
480 /* Store the address to the target's command block agent. */
481
482 dev->CommandBlockAgent_high = login_result.command_block_agent.high;
483 dev->CommandBlockAgent_low = login_result.command_block_agent.low;
484
485 dev->loginID = login_result.login_ID; /* Store the login ID. */
486
487 XPRINTF("Login response size: %u.", login_result.length);
488 XPRINTF("Signed into SBP-2 device node 0x%08x. Login ID: %u\n", dev->nodeID, dev->loginID);
489 break;
490#if 0
491 case SBP2_RECONNECT_REQUEST: /* Reconnect. */
492 /* Just return the result from ieee1394_Sync(). */
493 break;
494#endif
495 default:
496 XPRINTF("Warning! Unsupported management ORB type!\n");
497 }
498
499 /* Validate the fetch agent's CSR address. */
500 if ((dev->CommandBlockAgent_low < 0xF0010000) || ((dev->CommandBlockAgent_high & 0xFFFF) != 0x0000FFFF))
501 result = (-1);
502 }
503
504 return result;
505}
506
507int ieee1394_SendCommandBlockORB(struct SBP2Device *dev, struct CommandDescriptorBlock *firstCDB)
508{
509 int result, retries;
510 struct sbp2_pointer address;
511
512 memset((void *)&statusFIFO, 0, sizeof(statusFIFO));
513
514 address.low = (u32)firstCDB;
515 address.NodeID = dev->InitiatorNodeID;
516 address.high = 0;
517
518 retries = 0;
519
520 /* Write the pointer to the first ORB in the fetch agent's NEXT_ORB register. */
521 while ((result = iLinkTrWrite(dev->trContext, dev->CommandBlockAgent_high, dev->CommandBlockAgent_low + 0x08, &address, 8)) < 0) {
522 XPRINTF("Error writing to the Fetch Agent's ORB_POINTER register @ 0x%08lx %08lx. Code: %d.\n", dev->CommandBlockAgent_high, dev->CommandBlockAgent_low + 0x08, result);
523
524 DelayThread(200000);
525 ieee1394_ResetFetchAgent(dev);
526
527 retries++;
528 if (retries > 3)
529 return (-1);
530 }
531
532#if 0
533 /* Write a value to the fetch agent's DOORBELL register. */
534 result = 1;
535 if ((result = iLinkTrWrite(dev->trContext, dev->CommandBlockAgent_high, dev->CommandBlockAgent_low + 0x10, &result, 4)) < 0) {
536 XPRINTF("Error writing to the Fetch Agent's DOORBELL register @ 0x%08lx %08lx. Code: %d.\n", dev->CommandBlockAgent_high, dev->CommandBlockAgent_low + 0x10, result);
537 return -2;
538 }
539#endif
540
541 return 1;
542}
543
544/* static unsigned int alarm_cb(void *arg){
545 iSetEventFlag(sbp2_event_flag, ERROR_TIME_OUT);
546 return 0;
547} */
548
549static int ProcessStatus(void)
550{
551 u32 statusFIFO_result;
552 unsigned char status, resp, dead, sense, len;
553 int result;
554
555 statusFIFO_result = statusFIFO.status.status;
556 status = RESP_SBP_STATUS(statusFIFO_result);
557 resp = RESP_RESP(statusFIFO_result);
558 dead = RESP_DEAD(statusFIFO_result);
559 len = RESP_LEN(statusFIFO_result);
560 sense = ((statusFIFO.status.data[0]) >> 16) & 0xF;
561
562 XPRINTF("result: 0x%08lx; status: 0x%02x; RESP: 0x%02x; Dead: %u; len: 0x%02x; sense: 0x%02x.\n", statusFIFO_result, status, resp, dead, len, sense);
563 if (sense == 0)
564 sense = 1; /* Workaround for faulty firmwares: The sense code is 0 or was not sent when it's supposed to be sent. */
565
566 result = (((status == 0) || (status == 0x0B)) && (resp == 0) && (!dead) && (len == 1)) ? 0 : -sense;
567
568 if (result < 0) {
569 printf("result: 0x%08lx; status: 0x%02x; RESP: 0x%02x; Dead: %u; len: 0x%02x; sense: 0x%02x.\n", statusFIFO_result, status, resp, dead, len, sense);
570 }
571
572 return result;
573}
574
575/* This is declared as inline as there is only one call to it. */
576static inline int ieee1394_Sync_withTimeout(u32 n500mSecUnits)
577{
578 /* iop_sys_clock_t timeout_clk;
579 u32 ef_result;
580
581 USec2SysClock(n500mSecUnits * 500000, &timeout_clk);
582
583 SetAlarm(&timeout_clk, &alarm_cb, NULL);
584 WaitEventFlag(sbp2_event_flag, WRITE_REQ_INCOMING | ERROR_TIME_OUT, WEF_OR | WEF_CLEAR, &ef_result);
585
586 if (ef_result & ERROR_TIME_OUT) {
587 XPRINTF("-=Time out=-\n");
588 return (-1);
589 } else
590 CancelAlarm(&alarm_cb, NULL); */
591
592 unsigned int i = 0;
593
594 while (RESP_SRC(statusFIFO.status.status) == 0) {
595 if (i > n500mSecUnits * 10000) {
596 XPRINTF("-=Time out=-\n");
597 return (-1);
598 }
599
600 DelayThread(50);
601 i++;
602 };
603
604 return (ProcessStatus());
605}
606
607int ieee1394_Sync(void)
608{
609 // WaitEventFlag(sbp2_event_flag, WRITE_REQ_INCOMING, WEF_AND | WEF_CLEAR, NULL);
610
611 while (RESP_SRC(statusFIFO.status.status) == 0) {
612 DelayThread(50);
613 };
614
615 return (ProcessStatus());
616}
617
618void DeinitIEEE1394(void)
619{
620 TerminateThread(iLinkIntrCBThreadID);
621 DeleteThread(iLinkIntrCBThreadID);
622 DeleteEventFlag(sbp2_event_flag);
623}
624
625void *malloc(int NumBytes)
626{
627 int OldState;
628 void *buffer;
629
630 CpuSuspendIntr(&OldState);
631 buffer = AllocSysMemory(ALLOC_FIRST, NumBytes, NULL);
632 CpuResumeIntr(OldState);
633
634 return buffer;
635}
636
637void free(void *buffer)
638{
639 int OldState;
640
641 CpuSuspendIntr(&OldState);
642 FreeSysMemory(buffer);
643 CpuResumeIntr(OldState);
644}
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205