1 /*---------------------------------------------------------------------------*
2 Project: Host I/O Interface for HIO2
3 File: Hio2If.c
4
5 (C)2005 HUDSON SOFT
6
7 $Header: /home/cvsroot/SDK/build/demos/hio2demo/HioIf/src/Hio2If.c,v 1.2 2006/03/09 12:28:43 yasuh-to Exp $
8
9 $NoKeywords: $
10 *---------------------------------------------------------------------------*/
11
12 #include <stdio.h>
13 #include <stdarg.h>
14 #include <revolution.h>
15 #include "Hio2If.h"
16
17 //#define HIO2IF_DEBUG
18
19 // device information
20 static s32 hio2DevCount = 0;
21 static HIO2DeviceType hio2Devices[HIO2_CHAN_MAX + 1] =
22 {
23 HIO2_DEVICE_INVALID,
24 HIO2_DEVICE_INVALID,
25 HIO2_DEVICE_INVALID
26 };
27
28 // error
29 static HIO2IF_ERROR hio2LastError = HIO2IF_ERROR_NONE;
30 static char hio2Message[128] = { '\0' };
31
32 // status
33 static HIO2IF_STATUS hio2Status[HIO2_CHAN_MAX] =
34 {
35 {
36 HIO2_DEVICE_INVALID,
37 HIO2IF_INVALID_ID,
38 HIO2_INVALID_HANDLE_VALUE,
39 HIO2IF_MODE_NONE,
40 FALSE,
41 FALSE,
42 FALSE,
43 HIO2IF_ASYNC_NONE,
44 NULL,
45 0,
46 NULL
47 },
48 {
49 HIO2_DEVICE_INVALID,
50 HIO2IF_INVALID_ID,
51 HIO2_INVALID_HANDLE_VALUE,
52 HIO2IF_MODE_NONE,
53 FALSE,
54 FALSE,
55 FALSE,
56 HIO2IF_ASYNC_NONE,
57 NULL,
58 0,
59 NULL
60 },
61 };
62
63 // packet command for Open
64 static const u8 hio2PacketCmd[] =
65 {
66 HIO2IF_CMD_OPEN_RDONLY,
67 HIO2IF_CMD_OPEN_WRONLY,
68 HIO2IF_CMD_OPEN_RDWR,
69 };
70
71 // initialize flag
72 static BOOL hio2Initialized = FALSE;
73
74 // error strings
75 static const char* hio2ErrorStrings[HIO2IF_ERROR_MAX] =
76 {
77
78 #include "Hio2IfErr.str"
79
80 };
81
82 ///////////////////////////////////////////////////////////////////////////////
83 //
84 // inline function definition
85 //
86
87 // Gets HIO2IF_ID from HIO2 handle
88 static inline
hio2GetIdOfHandle(HIO2Handle h)89 s32 hio2GetIdOfHandle(HIO2Handle h)
90 {
91 return (hio2Status[0].hHIO == h) ? 0 : 1;
92 }
93
94 ///////////////////////////////////////////////////////////////////////////////
95 //
96 // callback definition
97 //
98
99 // HIO2EnumDevice() - callback
100 static
hio2EnumCallback(HIO2DeviceType type)101 BOOL hio2EnumCallback( HIO2DeviceType type )
102 {
103 #ifdef HIO2IF_DEBUG
104 OSReport("Device = %d\n", type);
105 #endif
106 hio2Devices[hio2DevCount++] = type;
107 return TRUE;
108 }
109
110 // callback for receive mail
111 static
hio2ReceiveCallback(HIO2Handle h)112 void hio2ReceiveCallback( HIO2Handle h )
113 {
114 s32 id;
115 HIO2IF_EVENT event;
116 u32 mail = 0;
117
118 (void)HIO2ReadMailbox(h, &mail);
119 id = hio2GetIdOfHandle(h);
120
121 switch ( HIO2IF_GET_PACKET_CMD(mail) )
122 {
123 case HIO2IF_CMD_OPEN_RESULT:
124 hio2Status[id].nPc = HIO2IF_GET_PACKET_CHAN(mail);
125 hio2Status[id].bConnect = TRUE;
126 event = HIO2IF_EVENT_CONNECT;
127 break;
128 case HIO2IF_CMD_SEND:
129 hio2Status[id].bReceived = TRUE;
130 event = HIO2IF_EVENT_RECEIVED;
131 break;
132 case HIO2IF_CMD_SEND_RESULT:
133 hio2Status[id].bSendPossible = TRUE;
134 event = HIO2IF_EVENT_SEND_POSSIBLE;
135 break;
136 case HIO2IF_CMD_CLOSE:
137 // the actual close process must be done in the application
138 hio2Status[id].bConnect = FALSE;
139 event = HIO2IF_EVENT_DISCONNECT;
140 break;
141 default:
142 event = HIO2IF_EVENT_UNKOWN;
143 }
144
145 // event callback function call
146 if ( hio2Status[id].fncCallback != NULL )
147 hio2Status[id].fncCallback(id, event);
148 }
149
150 // callback for HIO2ReadAsync()
151 static
hio2ReadAsyncCallback(HIO2Handle h)152 void hio2ReadAsyncCallback( HIO2Handle h )
153 {
154 s32 id = hio2GetIdOfHandle(h);
155 u32 async = HIO2IF_ASYNC_READ_MASK(hio2Status[id].dwAsyncMode);
156
157 DCInvalidateRange((void *)hio2Status[id].pReadAsyncPtr,
158 hio2Status[id].dwReadAsyncSize);
159
160 // If "async" is specified by Read, notify the connection target of the read completion; notification is unnecessary for ReadFree
161 //
162 if ( async & HIO2IF_ASYNC_READ )
163 {
164 (void)HIO2WriteMailbox(
165 hio2Status[id].hHIO,
166 HIO2IF_SET_PACKET(hio2Status[id].nType, HIO2IF_CMD_SEND_RESULT));
167 }
168
169 hio2Status[id].dwAsyncMode &= ~async;
170
171 // Event callback function call
172 if (hio2Status[id].fncCallback != NULL )
173 hio2Status[id].fncCallback(id, HIO2IF_EVENT_READ_ASYNC_DONE);
174 }
175
176 // Callback for HIO2WriteAsync()
177 static
hio2WriteAsyncCallback(HIO2Handle h)178 void hio2WriteAsyncCallback( HIO2Handle h )
179 {
180 s32 id = hio2GetIdOfHandle(h);
181 u32 async = HIO2IF_ASYNC_WRITE_MASK(hio2Status[id].dwAsyncMode);
182
183 // If "async" is specified by Write, notify the connection target of the write; notification is unnecessary for WriteFree
184 //
185 if ( async & HIO2IF_ASYNC_WRITE )
186 {
187 (void)HIO2WriteMailbox(
188 hio2Status[id].hHIO,
189 HIO2IF_SET_PACKET(hio2Status[id].nType, HIO2IF_CMD_SEND));
190 }
191
192 hio2Status[id].dwAsyncMode &= ~async;
193
194 // event callback function call
195 if ( hio2Status[id].fncCallback != NULL )
196 hio2Status[id].fncCallback(id, HIO2IF_EVENT_WRITE_ASYNC_DONE);
197 }
198
199 // callback for disconnect
200 static
hio2DisconnectCallback(HIO2Handle h)201 void hio2DisconnectCallback( HIO2Handle h )
202 {
203 s32 id = hio2GetIdOfHandle(h);
204
205 (void)sprintf(hio2Message, "INTERRUPT, EXI device(%d)",
206 hio2Status[id].nType);
207
208 // event callback function call
209 if ( hio2Status[id].fncCallback != NULL )
210 hio2Status[id].fncCallback(id, HIO2IF_EVENT_INTERRUPT);
211
212 hio2Status[id].nType = HIO2_DEVICE_INVALID;
213 hio2Status[id].nPc = HIO2IF_INVALID_ID;
214 hio2Status[id].hHIO = HIO2_INVALID_HANDLE_VALUE;
215 hio2Status[id].nMode = HIO2IF_MODE_NONE;
216 hio2Status[id].bConnect = FALSE;
217 hio2Status[id].bReceived = FALSE;
218 hio2Status[id].bSendPossible = FALSE;
219 hio2Status[id].fncCallback = NULL;
220 }
221
222 //-----------------------------------------------------------------------------
223 // local function definition
224
225 static
hio2SetFatal(HIO2IF_ERROR errID,...)226 HIO2IF_RESULT hio2SetFatal( HIO2IF_ERROR errID, ... )
227 {
228 va_list argptr;
229
230 va_start(argptr, errID);
231 (void)vsprintf(hio2Message, (char*)hio2ErrorStrings[errID], argptr);
232 va_end(argptr);
233
234 hio2LastError = errID;
235
236 return HIO2IF_RESULT_FATAL;
237 }
238
239 static
hio2SetError(HIO2IF_ERROR errID,...)240 HIO2IF_RESULT hio2SetError( HIO2IF_ERROR errID, ... )
241 {
242 va_list argptr;
243
244 va_start(argptr, errID);
245 (void)vsprintf(hio2Message, (char*)hio2ErrorStrings[errID], argptr);
246 va_end(argptr);
247
248 hio2LastError = errID;
249
250 return HIO2IF_RESULT_ERROR;
251 }
252
253 ///////////////////////////////////////////////////////////////////////////////
254 //
255 // Host I/O interface for NNGC
256 //
257
258 //-----------------------------------------------------------------------------
HIO2IFGetDeviceCount(void)259 s32 HIO2IFGetDeviceCount( void )
260 {
261 return hio2DevCount;
262 }
263
264 //-----------------------------------------------------------------------------
HIO2IFGetDevice(s32 index)265 HIO2DeviceType HIO2IFGetDevice( s32 index )
266 {
267 ASSERT((index >= 0) && (index < (HIO2_CHAN_MAX + 1)));
268 return hio2Devices[index];
269 }
270
271 //-----------------------------------------------------------------------------
HIO2IFInit(void)272 HIO2IF_RESULT HIO2IFInit( void )
273 {
274 // when initialized, terminate HIO2
275 if ( hio2Initialized ) HIO2Exit();
276
277 hio2DevCount = 0;
278 hio2Devices[0] = hio2Devices[1] =
279 hio2Status[0].nType = hio2Status[1].nType = HIO2_DEVICE_INVALID;
280
281 // HIO2 initialization
282 if ( !HIO2Init() )
283 return hio2SetFatal(HIO2IF_FATAL_INIT, HIO2GetLastError());
284
285 // search for an EXI device
286 if ( !HIO2EnumDevices(hio2EnumCallback) )
287 return hio2SetFatal(HIO2IF_FATAL_ENUMDEVICES, HIO2GetLastError());
288
289 hio2Initialized = TRUE;
290
291 return HIO2IF_RESULT_SUCCESS;
292 }
293
294 //-----------------------------------------------------------------------------
HIO2IFOpen(HIO2DeviceType type,HIO2IF_MODE mode,HIO2IF_EVENT_CALLBACK callback,HIO2IF_ID * id)295 HIO2IF_RESULT HIO2IFOpen( HIO2DeviceType type, HIO2IF_MODE mode,
296 HIO2IF_EVENT_CALLBACK callback, HIO2IF_ID* id )
297 {
298 *id = HIO2IF_INVALID_ID;
299
300 // When an EXI channel has not been detected
301 if ( type == HIO2_DEVICE_INVALID )
302 return hio2SetError(HIO2IF_ERROR_CHAN_NOT_FIND, type);
303
304 // When the specified EXI channel is in use
305 if ( (type == hio2Status[0].nType) || (type == hio2Status[1].nType) )
306 return hio2SetError(HIO2IF_ERROR_CHAN_ALREADY_OPENED, type);
307
308 // Search for an available ID
309 *id = (hio2Status[0].nType == HIO2IF_INVALID_ID) ? 0 : 1;
310
311 hio2Status[*id].hHIO =
312 HIO2Open(type, hio2ReceiveCallback, hio2DisconnectCallback);
313 if ( hio2Status[*id].hHIO == HIO2_INVALID_HANDLE_VALUE )
314 return hio2SetFatal(HIO2IF_FATAL_OPEN, type, HIO2GetLastError());
315
316 hio2Status[*id].nType = type;
317 hio2Status[*id].nMode = mode;
318 hio2Status[*id].bConnect = FALSE;
319 hio2Status[*id].bReceived = FALSE;
320 hio2Status[*id].bSendPossible = TRUE;
321 hio2Status[*id].fncCallback = callback;
322
323 // Open notification
324 (void)HIO2WriteMailbox(hio2Status[*id].hHIO,
325 HIO2IF_SET_PACKET(type, hio2PacketCmd[mode]));
326
327 return HIO2IF_RESULT_SUCCESS;
328 }
329
330 //-----------------------------------------------------------------------------
HIO2IFRead(HIO2IF_ID id,u32 addr,void * buffer,s32 size,BOOL async)331 HIO2IF_RESULT HIO2IFRead( HIO2IF_ID id, u32 addr, void* buffer, s32 size,
332 BOOL async )
333 {
334 if ( id == HIO2IF_INVALID_ID ) return hio2SetError(HIO2IF_ERROR_INVALID_ID);
335 // For the write-only mode
336 if ( hio2Status[id].nMode == HIO2IF_MODE_WRONLY )
337 return hio2SetError(HIO2IF_ERROR_WRITE_ONLY, hio2Status[id].nType);
338
339 // Not connected to the PC
340 if ( !hio2Status[id].bConnect )
341 return hio2SetError(HIO2IF_ERROR_NOT_CONNECT, hio2Status[id].nType);
342
343 // When data has not been received
344 if ( !hio2Status[id].bReceived )
345 return hio2SetError(HIO2IF_ERROR_NOT_RECV_DATA, hio2Status[id].nType);
346
347 hio2Status[id].bReceived = FALSE;
348
349 // Synchronous Read
350 if ( !async )
351 {
352 if ( !HIO2Read(hio2Status[id].hHIO, addr, buffer, size) )
353 return hio2SetFatal(HIO2IF_FATAL_READ,
354 hio2Status[id].nType, HIO2GetLastError());
355
356 DCInvalidateRange(buffer, (u32)size);
357
358 // Perform a Read completion notification to the connection target
359 (void)HIO2WriteMailbox(
360 hio2Status[id].hHIO,
361 HIO2IF_SET_PACKET(hio2Status[id].nType, HIO2IF_CMD_SEND_RESULT));
362 }
363 // Asynchronous Read
364 else
365 {
366 hio2Status[id].dwAsyncMode |= HIO2IF_ASYNC_READ;
367 hio2Status[id].pReadAsyncPtr = buffer;
368 hio2Status[id].dwReadAsyncSize = (u32)size;
369
370 if ( !HIO2ReadAsync(hio2Status[id].hHIO, addr, buffer, size,
371 hio2ReadAsyncCallback) )
372 return hio2SetFatal(HIO2IF_FATAL_READ,
373 hio2Status[id].nType, HIO2GetLastError());
374 }
375
376 return HIO2IF_RESULT_SUCCESS;
377 }
378
379 //-----------------------------------------------------------------------------
HIO2IFReadFree(HIO2IF_ID id,u32 addr,void * buffer,s32 size,BOOL async)380 HIO2IF_RESULT HIO2IFReadFree( HIO2IF_ID id, u32 addr, void* buffer, s32 size,
381 BOOL async )
382 {
383 if ( id == HIO2IF_INVALID_ID ) return hio2SetError(HIO2IF_ERROR_INVALID_ID);
384 // For the write-only mode
385 if ( hio2Status[id].nMode == HIO2IF_MODE_WRONLY )
386 return hio2SetError(HIO2IF_ERROR_WRITE_ONLY, hio2Status[id].nType);
387
388 // Not connected to the PC
389 if ( !hio2Status[id].bConnect )
390 return hio2SetError(HIO2IF_ERROR_NOT_CONNECT, hio2Status[id].nType);
391
392 // Synchronous Read
393 if ( !async )
394 {
395 if ( !HIO2Read(hio2Status[id].hHIO, addr, buffer, size) )
396 return hio2SetFatal(HIO2IF_FATAL_READ,
397 hio2Status[id].nType, HIO2GetLastError());
398
399 DCInvalidateRange(buffer, (u32)size);
400 }
401 // Asynchronous Read
402 else
403 {
404 // The previous ReadAsync or WriteAsync is not completed
405 if ( hio2Status[id].dwAsyncMode )
406 return hio2SetError(HIO2IF_ERROR_BUSY, hio2Status[id].nType);
407
408 hio2Status[id].dwAsyncMode |= HIO2IF_ASYNC_READ_FREE;
409 hio2Status[id].pReadAsyncPtr = buffer;
410 hio2Status[id].dwReadAsyncSize = (u32)size;
411
412 if ( !HIO2ReadAsync(hio2Status[id].hHIO, addr, buffer, size,
413 hio2ReadAsyncCallback) )
414 return hio2SetFatal(HIO2IF_FATAL_READ,
415 hio2Status[id].nType, HIO2GetLastError());
416
417 }
418
419 return HIO2IF_RESULT_SUCCESS;
420 }
421
422 //-----------------------------------------------------------------------------
HIO2IFWrite(HIO2IF_ID id,u32 addr,void * buffer,s32 size,BOOL async)423 HIO2IF_RESULT HIO2IFWrite( HIO2IF_ID id, u32 addr, void* buffer, s32 size,
424 BOOL async )
425 {
426 if ( id == HIO2IF_INVALID_ID ) return hio2SetError(HIO2IF_ERROR_INVALID_ID);
427 // For the read-only mode
428 if ( hio2Status[id].nMode == HIO2IF_MODE_RDONLY )
429 return hio2SetError(HIO2IF_ERROR_READ_ONLY, hio2Status[id].nType);
430
431 // Not connected to the PC
432 if ( !hio2Status[id].bConnect )
433 return hio2SetError(HIO2IF_ERROR_NOT_CONNECT, hio2Status[id].nType);
434
435 // When it can't be sent (when the target cannot receive data)
436 if ( !hio2Status[id].bSendPossible )
437 {
438 return hio2SetError(HIO2IF_ERROR_CANNOT_SEND_DATA,
439 hio2Status[id].nType);
440 }
441
442 hio2Status[id].bSendPossible = FALSE;
443
444 DCFlushRange(buffer, (u32)size);
445
446 // Synchronous Write
447 if ( !async )
448 {
449 if ( !HIO2Write(hio2Status[id].hHIO, addr, buffer, size) )
450 return hio2SetFatal(HIO2IF_FATAL_WRITE,
451 hio2Status[id].nType, HIO2GetLastError());
452
453 // Perform a Write notification to the connection target
454 (void)HIO2WriteMailbox(
455 hio2Status[id].hHIO,
456 HIO2IF_SET_PACKET(hio2Status[id].nType, HIO2IF_CMD_SEND));
457 }
458 // Asynchronous Write
459 else
460 {
461 hio2Status[id].dwAsyncMode |= HIO2IF_ASYNC_WRITE;
462 if ( !HIO2WriteAsync(hio2Status[id].hHIO, addr, buffer, size,
463 hio2WriteAsyncCallback) )
464 return hio2SetFatal(HIO2IF_FATAL_WRITE,
465 hio2Status[id].nType, HIO2GetLastError());
466 }
467
468 return HIO2IF_RESULT_SUCCESS;
469 }
470
471 //-----------------------------------------------------------------------------
HIO2IFWriteFree(HIO2IF_ID id,u32 addr,void * buffer,s32 size,BOOL async)472 HIO2IF_RESULT HIO2IFWriteFree( HIO2IF_ID id, u32 addr, void* buffer,
473 s32 size, BOOL async )
474 {
475 if ( id == HIO2IF_INVALID_ID ) return hio2SetError(HIO2IF_ERROR_INVALID_ID);
476 // For the read-only mode
477 if ( hio2Status[id].nMode == HIO2IF_MODE_RDONLY )
478 return hio2SetError(HIO2IF_ERROR_READ_ONLY, hio2Status[id].nType);
479
480 // Not connected to the PC
481 if ( !hio2Status[id].bConnect )
482 return hio2SetError(HIO2IF_ERROR_NOT_CONNECT, hio2Status[id].nType);
483
484 DCFlushRange(buffer, (u32)size);
485
486 // Synchronous Write
487 if ( !async )
488 {
489 if ( !HIO2Write(hio2Status[id].hHIO, addr, buffer, size) )
490 return hio2SetFatal(HIO2IF_FATAL_WRITE,
491 hio2Status[id].nType, HIO2GetLastError());
492 }
493 // Asynchronous Write
494 else
495 {
496 // The previous ReadAsync or WriteAsync is not completed
497 if ( hio2Status[id].dwAsyncMode )
498 return hio2SetError(HIO2IF_ERROR_BUSY, hio2Status[id].nType);
499
500 hio2Status[id].dwAsyncMode |= HIO2IF_ASYNC_WRITE_FREE;
501 if ( !HIO2WriteAsync(hio2Status[id].hHIO, addr, buffer, size,
502 hio2WriteAsyncCallback) )
503 return hio2SetFatal(HIO2IF_FATAL_WRITE,
504 hio2Status[id].nType, HIO2GetLastError());
505 }
506
507 return HIO2IF_RESULT_SUCCESS;
508 }
509
510 //-----------------------------------------------------------------------------
HIO2IFReadStatus(HIO2IF_ID id,u32 * status)511 HIO2IF_RESULT HIO2IFReadStatus( HIO2IF_ID id, u32* status )
512 {
513 if ( id == HIO2IF_INVALID_ID ) return hio2SetError(HIO2IF_ERROR_INVALID_ID);
514 // Not connected to the PC
515 if ( !hio2Status[id].bConnect )
516 return hio2SetError(HIO2IF_ERROR_NOT_CONNECT, hio2Status[id].nType);
517
518 return HIO2ReadStatus(hio2Status[id].hHIO, status)
519 ? HIO2IF_RESULT_SUCCESS
520 : hio2SetFatal(HIO2IF_FATAL_READSTATUS, hio2Status[id].nType,
521 HIO2GetLastError());
522 }
523
524 //-----------------------------------------------------------------------------
HIO2IFClose(HIO2IF_ID id)525 HIO2IF_RESULT HIO2IFClose( HIO2IF_ID id )
526 {
527 BOOL result;
528 s32 chan;
529
530 if ( id == HIO2IF_INVALID_ID ) return hio2SetError(HIO2IF_ERROR_INVALID_ID);
531 chan = hio2Status[id].nType;
532
533 // Perform a close notification when connected to the target
534 if ( hio2Status[id].bConnect )
535 {
536 (void)HIO2WriteMailbox(hio2Status[id].hHIO,
537 HIO2IF_SET_PACKET(chan, HIO2IF_CMD_CLOSE));
538 }
539
540 result = HIO2Close(hio2Status[id].hHIO);
541
542 hio2Status[id].nType = (HIO2DeviceType)HIO2IF_INVALID_ID;
543 hio2Status[id].nPc = HIO2IF_INVALID_ID;
544 hio2Status[id].hHIO = HIO2_INVALID_HANDLE_VALUE;
545 hio2Status[id].nMode = HIO2IF_MODE_NONE;
546 hio2Status[id].bConnect = FALSE;
547 hio2Status[id].bReceived = FALSE;
548 hio2Status[id].bSendPossible = FALSE;
549 hio2Status[id].fncCallback = NULL;
550
551 return result ? HIO2IF_RESULT_SUCCESS
552 : hio2SetFatal(HIO2IF_FATAL_CLOSE, chan, HIO2GetLastError());
553 }
554
555 //-----------------------------------------------------------------------------
HIO2IFSync(void)556 void HIO2IFSync( void )
557 {
558 // Perform an open notification when the EXI channel is opened, and a connection to the PC has not been made
559 //
560 if ( (hio2Status[0].hHIO != HIO2_INVALID_HANDLE_VALUE)
561 && (!hio2Status[0].bConnect) )
562 {
563 (void)HIO2WriteMailbox(
564 hio2Status[0].hHIO,
565 HIO2IF_SET_PACKET(hio2Status[0].nType,
566 hio2PacketCmd[hio2Status[0].nMode]));
567 }
568
569 if ( (hio2Status[1].hHIO != HIO2_INVALID_HANDLE_VALUE)
570 && (!hio2Status[1].bConnect) )
571 {
572 // Open notification
573 (void)HIO2WriteMailbox(
574 hio2Status[1].hHIO,
575 HIO2IF_SET_PACKET(hio2Status[1].nType,
576 hio2PacketCmd[hio2Status[1].nMode]));
577 }
578 }
579
580 //-----------------------------------------------------------------------------
HIO2IFExit(void)581 void HIO2IFExit( void )
582 {
583 // Perform a close notification when EXI channel is opened, and connection to the PC is available
584 if ( (hio2Status[0].hHIO != HIO2_INVALID_HANDLE_VALUE)
585 && (hio2Status[0].bConnect) )
586 {
587 (void)HIO2IFClose(0);
588 }
589
590 if ( (hio2Status[1].hHIO != HIO2_INVALID_HANDLE_VALUE)
591 && (hio2Status[1].bConnect) )
592 {
593 (void)HIO2IFClose(1);
594 }
595
596 // HIO2Exit() force-closes opened channels
597 HIO2Exit();
598
599 hio2Initialized = FALSE;
600 }
601
602 //-----------------------------------------------------------------------------
HIO2IFIsConnected(HIO2IF_ID id)603 BOOL HIO2IFIsConnected( HIO2IF_ID id )
604 {
605 return (id != HIO2IF_INVALID_ID) ? hio2Status[id].bConnect : FALSE;
606 }
607
608 //-----------------------------------------------------------------------------
HIO2IFIsReceived(HIO2IF_ID id)609 BOOL HIO2IFIsReceived( HIO2IF_ID id )
610 {
611 return (id != HIO2IF_INVALID_ID) ? hio2Status[id].bReceived : FALSE;
612 }
613
614 //-----------------------------------------------------------------------------
HIO2IFIsSendPossible(HIO2IF_ID id)615 BOOL HIO2IFIsSendPossible( HIO2IF_ID id )
616 {
617 return (id != HIO2IF_INVALID_ID) ? hio2Status[id].bSendPossible : FALSE;
618 }
619
620 //-----------------------------------------------------------------------------
HIO2IFGetDeviceType(HIO2IF_ID id)621 HIO2DeviceType HIO2IFGetDeviceType( HIO2IF_ID id )
622 {
623 return (id != HIO2IF_INVALID_ID)
624 ? hio2Status[id].nType : HIO2_DEVICE_INVALID;
625 }
626
627 //-----------------------------------------------------------------------------
HIO2IFGetPcChan(HIO2IF_ID id)628 s32 HIO2IFGetPcChan( HIO2IF_ID id )
629 {
630 return (id != HIO2IF_INVALID_ID) ? hio2Status[id].nPc : -1;
631 }
632
633 //-----------------------------------------------------------------------------
HIO2IFGetLastError(void)634 HIO2IF_ERROR HIO2IFGetLastError( void )
635 {
636 return hio2LastError;
637 }
638
639 //-----------------------------------------------------------------------------
HIO2IFGetErrorMessage(void)640 const char* HIO2IFGetErrorMessage( void )
641 {
642 return hio2Message;
643 }
644
645 // end of Hio2If.c
646