2 *----------------------------------------------------------------------------
3 * stir4200 class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
10 #include "stir4200.class.h"
13 static const STRPTR libname
= MOD_NAME_STRING
;
16 const APTR DevFuncTable
[] =
18 &AROS_SLIB_ENTRY(devOpen
, dev
, 1),
19 &AROS_SLIB_ENTRY(devClose
, dev
, 2),
20 &AROS_SLIB_ENTRY(devExpunge
, dev
, 3),
21 &AROS_SLIB_ENTRY(devReserved
, dev
, 4),
22 &AROS_SLIB_ENTRY(devBeginIO
, dev
, 5),
23 &AROS_SLIB_ENTRY(devAbortIO
, dev
, 6),
27 static int libInit(LIBBASETYPEPTR nh
)
29 struct NepClassSTIr4200
*ncp
;
30 struct NepSTIr4200Base
*ret
= NULL
;
32 KPRINTF(10, ("libInit nh: 0x%08lx SysBase: 0x%08lx\n", nh
, SysBase
));
34 nh
->nh_UtilityBase
= OpenLibrary("utility.library", 39);
36 #define UtilityBase nh->nh_UtilityBase
40 NewList(&nh
->nh_Units
);
42 if((nh
->nh_DevBase
= (struct NepSTIrDevBase
*) MakeLibrary((APTR
) DevFuncTable
, NULL
, (APTR
) devInit
,
43 sizeof(struct NepSTIrDevBase
), NULL
)))
45 nh
->nh_DevBase
->np_ClsBase
= nh
;
46 ncp
= &nh
->nh_DummyNCP
;
47 ncp
->ncp_CDC
= AllocVec(sizeof(struct ClsDevCfg
), MEMF_PUBLIC
|MEMF_CLEAR
);
50 ncp
->ncp_ClsBase
= nh
;
51 ncp
->ncp_Device
= NULL
;
53 AddDevice((struct Device
*) nh
->nh_DevBase
);
54 nh
->nh_DevBase
->np_Library
.lib_OpenCnt
++;
59 KPRINTF(20, ("failed to create usbstir4200.device\n"));
63 CloseLibrary(UtilityBase
);
66 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
69 KPRINTF(10, ("libInit: Ok\n"));
70 return(ret
? TRUE
: FALSE
);
73 static int libOpen(LIBBASETYPEPTR nh
)
75 KPRINTF(10, ("libOpen nh: 0x%08lx\n", nh
));
80 static int libExpunge(LIBBASETYPEPTR nh
)
82 struct NepClassSTIr4200
*ncp
;
84 KPRINTF(10, ("libExpunge nh: 0x%08lx\n", nh
));
86 if(nh
->nh_DevBase
->np_Library
.lib_OpenCnt
== 1)
88 KPRINTF(1, ("libExpunge: closelibrary utilitybase 0x%08lx\n",
90 CloseLibrary((struct Library
*) UtilityBase
);
92 ncp
= (struct NepClassSTIr4200
*) nh
->nh_Units
.lh_Head
;
93 while(ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
)
95 Remove((struct Node
*) ncp
);
96 FreeVec(ncp
->ncp_CDC
);
98 ncp
= (struct NepClassSTIr4200
*) nh
->nh_Units
.lh_Head
;
101 nh
->nh_DevBase
->np_Library
.lib_OpenCnt
--;
102 RemDevice((struct Device
*) nh
->nh_DevBase
);
104 KPRINTF(5, ("libExpunge: Unloading done! stir4200.class expunged!\n\n"));
106 KPRINTF(5, ("libExpunge: Could not expunge, LIBF_DELEXP set!\n"));
113 ADD2INITLIB(libInit
, 0)
114 ADD2OPENLIB(libOpen
, 0)
115 ADD2EXPUNGELIB(libExpunge
, 0)
119 * ***********************************************************************
120 * * Library functions *
121 * ***********************************************************************
124 /* /// "usbAttemptDeviceBinding()" */
125 struct NepClassSTIr4200
* usbAttemptDeviceBinding(struct NepSTIr4200Base
*nh
, struct PsdDevice
*pd
)
130 KPRINTF(1, ("nepSTIr4200AttemptDeviceBinding(%08lx)\n", pd
));
132 if((ps
= OpenLibrary("poseidon.library", 4)))
134 psdGetAttrs(PGA_DEVICE
, pd
,
135 DA_VendorID
, &vendid
,
136 DA_ProductID
, &prodid
,
139 if((vendid
== 0x066F) && (prodid
== 0x4200))
141 return(usbForceDeviceBinding(nh
, pd
));
148 /* /// "usbForceDeviceBinding()" */
149 struct NepClassSTIr4200
* usbForceDeviceBinding(struct NepSTIr4200Base
*nh
, struct PsdDevice
*pd
)
152 struct NepClassSTIr4200
*ncp
;
153 struct NepClassSTIr4200
*tmpncp
;
154 struct ClsDevCfg
*cdc
;
162 struct Task
*tmptask
;
164 KPRINTF(1, ("nepSTIr4200ForceDeviceBinding(%08lx)\n", pd
));
166 if((ps
= OpenLibrary("poseidon.library", 4)))
168 psdGetAttrs(PGA_DEVICE
, pd
,
169 DA_ProductID
, &prodid
,
170 DA_VendorID
, &vendid
,
171 DA_ProductName
, &devname
,
172 DA_IDString
, &devidstr
,
177 ncp
= (struct NepClassSTIr4200
*) nh
->nh_Units
.lh_Head
;
178 while(ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
)
182 unitno
= ncp
->ncp_UnitNo
;
186 ncp
= (struct NepClassSTIr4200
*) ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
;
190 /* as units are freed in the expunge-vector, the memory is
191 outside the scope of the poseidon library */
192 if(!(ncp
= AllocVec(sizeof(struct NepClassSTIr4200
), MEMF_PUBLIC
|MEMF_CLEAR
)))
198 ncp
->ncp_CDC
= cdc
= AllocVec(sizeof(struct ClsDevCfg
), MEMF_PUBLIC
|MEMF_CLEAR
);
206 /* IORequests may be queued even if the task is gone. */
207 ncp
->ncp_UnitNo
= (ULONG
) -1;
208 NewList(&ncp
->ncp_Unit
.unit_MsgPort
.mp_MsgList
);
209 NewList(&ncp
->ncp_ReadQueue
);
210 NewList(&ncp
->ncp_WriteQueue
);
211 AddTail(&nh
->nh_Units
, &ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
);
213 ncp
->ncp_ClsBase
= nh
;
214 ncp
->ncp_Device
= pd
;
215 ncp
->ncp_UnitProdID
= prodid
;
216 ncp
->ncp_UnitVendorID
= vendid
;
217 ncp
->ncp_DevIDString
= devidstr
;
219 nLoadBindingConfig(ncp
);
221 /* Find next free unit number */
222 if(unitno
== (ULONG
) -1)
224 unitno
= ncp
->ncp_CDC
->cdc_DefaultUnit
;
225 tmpncp
= (struct NepClassSTIr4200
*) nh
->nh_Units
.lh_Head
;
226 while(tmpncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
)
228 if(tmpncp
->ncp_UnitNo
== unitno
)
231 tmpncp
= (struct NepClassSTIr4200
*) nh
->nh_Units
.lh_Head
;
233 tmpncp
= (struct NepClassSTIr4200
*) tmpncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
;
237 ncp
->ncp_UnitNo
= unitno
;
240 psdSafeRawDoFmt(buf
, 64, "stir4200.class<%08lx>", ncp
);
241 ncp
->ncp_ReadySignal
= SIGB_SINGLE
;
242 ncp
->ncp_ReadySigTask
= FindTask(NULL
);
243 SetSignal(0, SIGF_SINGLE
);
244 if((tmptask
= psdSpawnSubTask(buf
, nSTIr4200Task
, ncp
)))
246 psdBorrowLocksWait(tmptask
, 1UL<<ncp
->ncp_ReadySignal
);
249 ncp
->ncp_ReadySigTask
= NULL
;
250 //FreeSignal(ncp->ncp_ReadySignal);
251 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
252 "Look at this infra red face '%s' at %s unit %ld!",
253 devname
, nh
->nh_DevBase
->np_Library
.lib_Node
.ln_Name
,
260 ncp
->ncp_ReadySigTask
= NULL
;
261 //FreeSignal(ncp->ncp_ReadySignal);
262 /* Get rid of unit structure */
264 Remove((struct Node *) ncp);
265 FreeVec(ncp->ncp_CDC);
274 /* /// "usbReleaseDeviceBinding()" */
275 void usbReleaseDeviceBinding(struct NepSTIr4200Base
*nh
, struct NepClassSTIr4200
*ncp
)
280 KPRINTF(1, ("nepSTIr4200ReleaseDeviceBinding(%08lx)\n", ncp
));
281 if((ps
= OpenLibrary("poseidon.library", 4)))
284 ncp
->ncp_ReadySignal
= SIGB_SINGLE
;
285 ncp
->ncp_ReadySigTask
= FindTask(NULL
);
288 Signal(ncp
->ncp_Task
, SIGBREAKF_CTRL_C
);
293 Wait(1L<<ncp
->ncp_ReadySignal
);
295 //FreeSignal(ncp->ncp_ReadySignal);
296 psdGetAttrs(PGA_DEVICE
, ncp
->ncp_Device
, DA_ProductName
, &devname
, TAG_END
);
297 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
298 "'%s' turned into a infrared dwarf.",
306 /* /// "usbGetAttrsA()" */
307 AROS_LH3(LONG
, usbGetAttrsA
,
308 AROS_LHA(ULONG
, type
, D0
),
309 AROS_LHA(APTR
, usbstruct
, A0
),
310 AROS_LHA(struct TagItem
*, tags
, A1
),
311 LIBBASETYPEPTR
, nh
, 5, nep
)
318 KPRINTF(1, ("nepSTIr4200GetAttrsA(%ld, %08lx, %08lx)\n", type
, usbstruct
, tags
));
322 if((ti
= FindTagItem(UCCA_Priority
, tags
)))
324 *((SIPTR
*) ti
->ti_Data
) = 0;
327 if((ti
= FindTagItem(UCCA_Description
, tags
)))
329 *((STRPTR
*) ti
->ti_Data
) = "IrDA Bridge for STIr4200 chipsets via usbstir4200.device";
332 if((ti
= FindTagItem(UCCA_HasClassCfgGUI
, tags
)))
334 *((IPTR
*) ti
->ti_Data
) = TRUE
;
337 if((ti
= FindTagItem(UCCA_HasBindingCfgGUI
, tags
)))
339 *((IPTR
*) ti
->ti_Data
) = TRUE
;
342 if((ti
= FindTagItem(UCCA_AfterDOSRestart
, tags
)))
344 *((IPTR
*) ti
->ti_Data
) = FALSE
;
347 if((ti
= FindTagItem(UCCA_UsingDefaultCfg
, tags
)))
349 *((IPTR
*) ti
->ti_Data
) = nh
->nh_DummyNCP
.ncp_UsingDefaultCfg
;
355 if((ti
= FindTagItem(UCBA_UsingDefaultCfg
, tags
)))
357 *((IPTR
*) ti
->ti_Data
) = ((struct NepClassSTIr4200
*) usbstruct
)->ncp_UsingDefaultCfg
;
367 /* /// "usbSetAttrsA()" */
368 AROS_LH3(LONG
, usbSetAttrsA
,
369 AROS_LHA(ULONG
, type
, D0
),
370 AROS_LHA(APTR
, usbstruct
, A0
),
371 AROS_LHA(struct TagItem
*, tags
, A1
),
372 LIBBASETYPEPTR
, nh
, 6, nep
)
380 /* /// "usbDoMethodA()" */
381 AROS_LH2(IPTR
, usbDoMethodA
,
382 AROS_LHA(ULONG
, methodid
, D0
),
383 AROS_LHA(IPTR
*, methoddata
, A1
),
384 LIBBASETYPEPTR
, nh
, 7, nep
)
388 struct NepClassSTIr4200
*ncp
;
390 KPRINTF(10, ("Do Method %ld\n", methodid
));
393 case UCM_AttemptDeviceBinding
:
394 return((IPTR
) usbAttemptDeviceBinding(nh
, (struct PsdDevice
*) methoddata
[0]));
396 case UCM_ForceDeviceBinding
:
397 return((IPTR
) usbForceDeviceBinding(nh
, (struct PsdDevice
*) methoddata
[0]));
399 case UCM_ReleaseDeviceBinding
:
400 usbReleaseDeviceBinding(nh
, (struct NepClassSTIr4200
*) methoddata
[0]);
403 case UCM_OpenCfgWindow
:
404 return(nOpenBindingCfgWindow(nh
, &nh
->nh_DummyNCP
));
406 case UCM_OpenBindingCfgWindow
:
407 return(nOpenBindingCfgWindow(nh
, (struct NepClassSTIr4200
*) methoddata
[0]));
409 case UCM_ConfigChangedEvent
:
410 nLoadClassConfig(nh
);
412 ncp
= (struct NepClassSTIr4200
*) nh
->nh_Units
.lh_Head
;
413 while(ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
)
415 nLoadBindingConfig(ncp
);
416 ncp
= (struct NepClassSTIr4200
*) ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
;
429 /* /// "nLoadClassConfig()" */
430 BOOL
nLoadClassConfig(struct NepSTIr4200Base
*nh
)
432 struct NepClassSTIr4200
*ncp
= &nh
->nh_DummyNCP
;
434 struct ClsDevCfg
*cdc
;
435 struct PsdIFFContext
*pic
;
437 KPRINTF(10, ("Loading Class Config...\n"));
442 if(!(ps
= OpenLibrary("poseidon.library", 4)))
448 /* Create default config */
450 cdc
->cdc_ChunkID
= AROS_LONG2BE(MAKE_ID('S','T','I','R'));
451 cdc
->cdc_Length
= AROS_LONG2BE(sizeof(struct ClsDevCfg
)-8);
452 cdc
->cdc_DefaultUnit
= 0;
453 cdc
->cdc_StackAuto
= TRUE
;
454 cdc
->cdc_TXPower
= 0;
455 cdc
->cdc_RXSense
= 1;
456 ncp
->ncp_UsingDefaultCfg
= TRUE
;
457 /* try to load default config */
458 pic
= psdGetClsCfg(libname
);
461 cdc
= psdGetCfgChunk(pic
, ncp
->ncp_CDC
->cdc_ChunkID
);
464 CopyMem(((UBYTE
*) cdc
) + 8, ((UBYTE
*) ncp
->ncp_CDC
) + 8, min(AROS_LONG2BE(cdc
->cdc_Length
), AROS_LONG2BE(ncp
->ncp_CDC
->cdc_Length
)));
466 ncp
->ncp_UsingDefaultCfg
= FALSE
;
475 /* /// "nLoadBindingConfig()" */
476 BOOL
nLoadBindingConfig(struct NepClassSTIr4200
*ncp
)
478 struct NepSTIr4200Base
*nh
= ncp
->ncp_ClsBase
;
480 struct ClsDevCfg
*cdc
;
481 struct PsdIFFContext
*pic
;
483 KPRINTF(10, ("Loading Binding Config...\n"));
488 //nLoadClassConfig(nh);
489 *ncp
->ncp_CDC
= *nh
->nh_DummyNCP
.ncp_CDC
;
490 ncp
->ncp_UsingDefaultCfg
= TRUE
;
492 if(!(ps
= OpenLibrary("poseidon.library", 4)))
499 pic
= psdGetUsbDevCfg(libname
, ncp
->ncp_DevIDString
, NULL
);
502 cdc
= psdGetCfgChunk(pic
, ncp
->ncp_CDC
->cdc_ChunkID
);
505 CopyMem(((UBYTE
*) cdc
) + 8, ((UBYTE
*) ncp
->ncp_CDC
) + 8, min(AROS_LONG2BE(cdc
->cdc_Length
), AROS_LONG2BE(ncp
->ncp_CDC
->cdc_Length
)));
507 ncp
->ncp_UsingDefaultCfg
= FALSE
;
516 /* /// "nOpenBindingCfgWindow()" */
517 LONG
nOpenBindingCfgWindow(struct NepSTIr4200Base
*nh
, struct NepClassSTIr4200
*ncp
)
520 KPRINTF(10, ("Opening GUI...\n"));
521 if(!(ps
= OpenLibrary("poseidon.library", 4)))
526 if(!ncp
->ncp_GUITask
)
528 if((ncp
->ncp_GUITask
= psdSpawnSubTask(MOD_NAME_STRING
" GUI", nGUITask
, ncp
)))
541 /**************************************************************************/
544 #define ps ncp->ncp_Base
546 /* /// "FCS Checksum tables" */
547 static UWORD FCS16Table
[256] =
549 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
550 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
551 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
552 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
553 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
554 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
555 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
556 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
557 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
558 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
559 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
560 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
561 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
562 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
563 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
564 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
565 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
566 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
567 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
568 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
569 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
570 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
571 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
572 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
573 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
574 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
575 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
576 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
577 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
578 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
579 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
580 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
583 static ULONG FCS32Table
[256] =
585 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
586 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
587 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
588 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
589 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
590 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
591 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
592 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
593 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
594 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
595 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
596 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
597 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
598 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
599 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
600 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
601 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
602 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
603 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
604 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
605 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
606 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
607 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
608 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
609 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
610 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
611 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
612 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
613 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
614 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
615 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
616 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
617 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
618 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
619 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
620 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
621 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
622 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
623 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
624 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
625 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
626 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
627 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
628 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
629 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
630 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
631 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
632 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
633 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
634 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
635 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
636 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
637 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
638 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
639 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
640 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
641 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
642 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
643 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
644 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
645 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
646 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
647 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
648 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
653 /* /// "nCalcFCS16()" */
654 UWORD
nCalcFCS16(UBYTE
*buf
, ULONG len
)
656 register UWORD crc
= 0;
661 crc
= ((crc
>>8) & 0xff) ^ FCS16Table
[(crc
^ (*buf
++)) & 0xff)];
664 return(crc
^ 0xffff);
668 /* /// "nCalcFCS32()" */
669 ULONG
nCalcFCS16(UBYTE
*buf
, ULONG len
)
671 register ULONG crc
= 0;
676 crc
= ((crc
>>8) & 0xff) ^ FCS32Table
[(crc
^ (*buf
++)) & 0xff)];
679 return(crc
^ 0xffffffff);
683 #define CRC32_POLYNOMIAL 0x04c11db7
685 /* /// "nCalcFCS32()" */
686 ULONG
nCalcFCS32(UBYTE
*buf
, ULONG len
)
688 ULONG crc
= 0xffffffff;
695 // could be optimized by lookup table.
699 if(((LONG
) (crc
^ (data
<<31))) < 0)
702 crc
^= CRC32_POLYNOMIAL
;
715 /* /// "nSetBaudrate()" */
716 BOOL
nSetBaudrate(struct NepClassSTIr4200
*ncp
, ULONG baudrate
)
718 ULONG mode
= SMF_FFSPRST
|SMF_FASTRXEN
;
726 res
= nSetReg(ncp
, STREG_CTRL
, SCF_SRESET
);
727 res
&= nSetReg(ncp
, STREG_DPLLTUNE
, 0x15);
728 ncp
->ncp_FIRMode
= FALSE
;
735 if(!clk
) clk
= PDCLK_9600
;
737 if(!clk
) clk
= PDCLK_19200
;
739 if(!clk
) clk
= PDCLK_38400
;
741 if(!clk
) clk
= PDCLK_57600
;
743 if(!clk
) clk
= PDCLK_115200
;
744 KPRINTF(1, ("Setting SIR Mode (%ld baud)!\n", baudrate
));
745 nSetReg(ncp
, STREG_BAUDRATE
, clk
);
750 KPRINTF(1, ("Setting FIR Mode!\n"));
751 ncp
->ncp_FIRMode
= TRUE
;
752 res
&= nSetReg(ncp
, STREG_BAUDRATE
, PDCLK_4000000
);
753 mode
|= SMF_FIR
|SMF_FASTRSTEN
;
757 KPRINTF(10, ("Unsupported baudrate %ld\n", baudrate
));
758 // set 9600 as default
759 nSetReg(ncp
, STREG_BAUDRATE
, PDCLK_9600
);
762 ncp
->ncp_BaudRate
= 9600;
766 ncp
->ncp_BaudRate
= baudrate
;
768 res
&= nSetReg(ncp
, STREG_MODE
, mode
);
769 res
&= nSetReg(ncp
, STREG_CTRL
, SCF_SDMODE
|SCF_TXPWR_HIGH
);
770 res
&= nSetReg(ncp
, STREG_CTRL
, SCF_TXPWR_HIGH
);
771 res
&= nSetReg(ncp
, STREG_SENSITIVITY
, 1<<SSB_RXDSNS
);
776 #define STUFFBYTEFIR(data) \
777 if((data >= 0x7d) && (data <= 0x7f)) \
784 #define STUFFBYTEFIRFCS(data) \
785 crc = ((crc>>8) & 0xff) ^ FCS32Table[(crc ^ data) & 0xff]; \
788 #define STUFFBYTESIR(data) \
789 if((data == 0xc0) || (data == 0xc1) || (data == 0x7d)) \
796 #define STUFFBYTESIRFCS(data) \
797 crc = ((crc>>8) & 0xff) ^ FCS16Table[(crc ^ data) & 0xff]; \
800 /* /// "nSendFrame()" */
801 BOOL
nSendFrame(struct NepClassSTIr4200
*ncp
, struct IOIrDAReq
*ioreq
)
803 UBYTE
*buf
= ncp
->ncp_WriteBuffer
;
805 ULONG datalen
= ioreq
->ioir_Length
;
806 UBYTE
*dataptr
= ioreq
->ioir_Data
;
810 register ULONG crc
= 0xffffffff;
811 // maximum size of frame: 2 (header) + 2 (len) + 16 (preamble) + 2 (BOF) + 4 (AC) + 2*datalen + 8 (FCS) + 2 (EOF)
812 if(datalen
<<1 > DEFBUFFERSIZE
- 36)
814 ioreq
->ioir_Req
.io_Error
= IRIOERR_OUTOFMEMORY
;
817 *buf
++ = 0x55; // header
819 buf
+= 2; // length of frame needs to be filled out later
821 *((ULONG
*) buf
) = 0x7f7f7f7f;
822 ((ULONG
*) buf
)[1] = 0x7f7f7f7f;
823 ((ULONG
*) buf
)[2] = 0x7f7f7f7f;
824 ((ULONG
*) buf
)[3] = 0x7f7f7f7f;
828 STUFFBYTEFIRFCS(ioreq
->ioir_Address
); // address byte
829 STUFFBYTEFIRFCS(ioreq
->ioir_Control
); // control byte
837 STUFFBYTEFIRFCS(data
);
856 register UWORD crc
= 0xffff;
857 // maximum size of frame: 2 (header) + 2 (len) + NumBOFs + 4 (AC) + 2*datalen + 4 (FCS) + 1 (EOF)
858 if(datalen
<<1 > DEFBUFFERSIZE
- 13 - ioreq
->ioir_NumBOFs
)
860 ioreq
->ioir_Req
.io_Error
= IRIOERR_OUTOFMEMORY
;
863 *buf
++ = 0x55; // header
865 buf
+= 2; // length of frame needs to be filled out later
867 if((framelen
= ioreq
->ioir_NumBOFs
))
874 STUFFBYTESIRFCS(ioreq
->ioir_Address
); // address byte
875 STUFFBYTESIRFCS(ioreq
->ioir_Control
); // control byte
883 STUFFBYTESIRFCS(data
);
895 framelen
= ((IPTR
) buf
) - ((IPTR
) &ncp
->ncp_WriteBuffer
[4]);
896 ncp
->ncp_WriteBuffer
[2] = framelen
;
897 ncp
->ncp_WriteBuffer
[3] = framelen
>>8;
898 KPRINTF(10, ("Sending Frame (%ld bytes)\n", framelen
));
899 DB(dumpmem(ncp
->ncp_WriteBuffer
, framelen
+4));
900 psdSendPipe(ncp
->ncp_EPOutPipe
, ncp
->ncp_WriteBuffer
, framelen
+4);
901 ncp
->ncp_WritePending
= ioreq
;
906 /* /// "nReceiveFrame()" */
907 ULONG
nReceiveFrame(struct NepClassSTIr4200
*ncp
, UBYTE
*buf
, ULONG len
)
909 struct IOIrDAReq
*ioreq
;
915 ioreq
= (struct IOIrDAReq
*) ncp
->ncp_ReadQueue
.lh_Head
;
916 if(!ioreq
->ioir_Req
.io_Message
.mn_Node
.ln_Succ
)
920 //KPRINTF(10, ("Receive frame:\n"));
921 //DB(dumpmem(buf, len));
924 KPRINTF(10, ("FIR Mode not yet implemented\n"));
926 register UWORD crc
= 0;
927 if(ncp
->ncp_UnescapeFirst
)
930 ncp
->ncp_UnescapeFirst
= FALSE
;
932 datalen
= ioreq
->ioir_Length
+ 2;
937 if(ncp
->ncp_FrameStarted
)
939 switch(data
= *buf
++)
942 if(ioreq
->ioir_Actual
)
944 KPRINTF(1, ("Unexpected BOF\n"));
945 ioreq
->ioir_NumBOFs
= 0;
947 KPRINTF(1, ("More BOFs...\n"));
948 ioreq
->ioir_NumBOFs
++;
950 ioreq
->ioir_Actual
= 0;
955 KPRINTF(1, ("EOF\n"));
956 ncp
->ncp_FrameStarted
= FALSE
;
958 if(ioreq
->ioir_Actual
> 3) // address+control field+FCS
960 ioreq
->ioir_Actual
-= 4;
961 crc
= 0xff ^ FCS16Table
[(0xff ^ ioreq
->ioir_Address
) & 0xff];
962 crc
= ((crc
>>8) & 0xff) ^ FCS16Table
[(crc
^ ioreq
->ioir_Control
) & 0xff];
963 cnt
= ioreq
->ioir_Actual
+ 2;
964 dataptr
= ioreq
->ioir_Data
;
967 crc
= ((crc
>>8) & 0xff) ^ FCS16Table
[(crc
^ *dataptr
++) & 0xff];
969 KPRINTF(10, ("CRC=%04lx for %ld bytes (%ld remaining)\n", crc
, ioreq
->ioir_Actual
, len
));
972 KPRINTF(10, ("CRC Error\n"));
976 KPRINTF(10, ("Frame too short\n"));
980 Remove((struct Node
*) ioreq
);
981 ReplyMsg((struct Message
*) ioreq
);
982 // is there another request pending?
983 ioreq
= (struct IOIrDAReq
*) ncp
->ncp_ReadQueue
.lh_Head
;
984 if(ioreq
->ioir_Req
.io_Message
.mn_Node
.ln_Succ
)
986 // don't try to switch baudrates, if a write request is pending with different baudrate
987 if(ncp
->ncp_BaudRate
!= ioreq
->ioir_Baud
)
989 KPRINTF(10, ("Baudrate change requested\n"));
990 return(0); // obviously, remaining frames (if any) are discarded
992 datalen
= ioreq
->ioir_Length
+ 2;
999 KPRINTF(1, ("Unescaping\n"));
1002 data
= *buf
++ ^ 0x20;
1003 if(!((data
== 0xc0) || (data
== 0xc1) || (data
== 0x7d)))
1005 // illegal escaped sequence
1006 KPRINTF(10, ("Illegal escaped code %02lx\n", data
));
1007 ncp
->ncp_FrameStarted
= FALSE
;
1011 KPRINTF(10, ("End of buffer, unescape first set\n"));
1012 ncp
->ncp_UnescapeFirst
= TRUE
;
1018 if(ioreq
->ioir_Actual
> 1)
1020 if(ioreq
->ioir_Actual
< datalen
)
1022 ((UBYTE
*) ioreq
->ioir_Data
)[ioreq
->ioir_Actual
-2] = data
;
1024 KPRINTF(10, ("Buffer overflow!\n"));
1025 ncp
->ncp_FrameStarted
= FALSE
;
1026 ioreq
->ioir_Req
.io_Error
= IRIOERR_OVERFLOW
;
1027 ioreq
->ioir_Actual
-= 2;
1028 Remove((struct Node
*) ioreq
);
1029 ReplyMsg((struct Message
*) ioreq
);
1033 if(ioreq
->ioir_Actual
)
1035 KPRINTF(1, ("Control: %02lx\n", data
));
1036 ioreq
->ioir_Control
= data
;
1038 KPRINTF(1, ("Address: %02lx\n", data
));
1039 ioreq
->ioir_Address
= data
;
1042 ioreq
->ioir_Actual
++;
1048 KPRINTF(1, ("BOF!\n"));
1049 ncp
->ncp_FrameStarted
= TRUE
;
1050 ioreq
->ioir_Actual
= 0;
1051 ioreq
->ioir_NumBOFs
= 1;
1056 KPRINTF(1, ("Last byte: %02lx\n", buf
[-1]));
1062 /* /// "nSTIr4200Task()" */
1063 AROS_UFH0(void, nSTIr4200Task
)
1067 struct NepClassSTIr4200
*ncp
;
1073 struct IOIrDAReq
*ioreq
;
1074 struct IOIrDAReq
*ioreq2
;
1075 ULONG mediabusycnt
= 0;
1077 if((ncp
= nAllocSTIr4200()))
1080 if(ncp
->ncp_ReadySigTask
)
1082 Signal(ncp
->ncp_ReadySigTask
, 1L<<ncp
->ncp_ReadySignal
);
1087 sigmask
= (1L<<ncp
->ncp_Unit
.unit_MsgPort
.mp_SigBit
)|(1L<<ncp
->ncp_TaskMsgPort
->mp_SigBit
)|SIGBREAKF_CTRL_C
;
1090 while((pp
= (struct PsdPipe
*) GetMsg(ncp
->ncp_TaskMsgPort
)))
1092 KPRINTF(1, ("Pipe back %08lx\n", pp
));
1093 if(pp
== ncp
->ncp_EPInPipe
)
1096 ioerr
= psdGetPipeError(pp
);
1097 len
= psdGetPipeActual(pp
);
1098 KPRINTF(1, ("Len = %ld\n", len
));
1101 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) libname
,
1102 "STIr4200 receive failed: %s (%ld)",
1103 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
1111 DB(dumpmem(ncp
->ncp_ReadBuffer
, len
));
1112 ncp
->ncp_RBufRemain
= nReceiveFrame(ncp
, ncp
->ncp_ReadBuffer
, len
);
1113 if(ncp
->ncp_RBufRemain
)
1115 // data not fully read -- wait for next request to arrive
1116 ncp
->ncp_RBufOffset
= len
- ncp
->ncp_RBufRemain
;
1117 KPRINTF(1, ("%ld Bytes at %ld remaining...\n", ncp
->ncp_RBufRemain
, ncp
->ncp_RBufOffset
));
1120 ncp
->ncp_ReadPending
= NULL
;
1122 if(pp
== ncp
->ncp_EPOutPipe
)
1124 if((ioreq
= ncp
->ncp_WritePending
))
1126 ioerr
= psdGetPipeError(pp
);
1129 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) libname
,
1130 "STIr4200 send failed: %s (%ld)",
1131 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
1132 ioreq
->ioir_Req
.io_Error
= IRIOERR_HOSTERROR
;
1133 ioreq
->ioir_Actual
= 0;
1135 ioreq
->ioir_Actual
= ioreq
->ioir_Length
;
1137 ReplyMsg((struct Message
*) ioreq
);
1138 ncp
->ncp_WritePending
= NULL
;
1143 while((ioreq
= (struct IOIrDAReq
*) GetMsg(&ncp
->ncp_Unit
.unit_MsgPort
)))
1145 KPRINTF(5, ("command ioreq: 0x%08lx cmd: %lu len: %ld\n",
1146 ioreq
, ioreq
->ioir_Req
.io_Command
, ioreq
->ioir_Length
));
1147 switch(ioreq
->ioir_Req
.io_Command
)
1150 ioreq
->ioir_Actual
= 0;
1152 AddTail(&ncp
->ncp_ReadQueue
, &ioreq
->ioir_Req
.io_Message
.mn_Node
);
1157 ioreq
->ioir_Actual
= 0;
1159 AddTail(&ncp
->ncp_WriteQueue
, &ioreq
->ioir_Req
.io_Message
.mn_Node
);
1164 ReplyMsg((struct Message
*) ioreq
);
1168 /* Reset does a flush too */
1170 ioreq2
= (struct IOIrDAReq
*) ncp
->ncp_ReadQueue
.lh_Head
;
1171 while(ioreq2
->ioir_Req
.io_Message
.mn_Node
.ln_Succ
)
1173 Remove((struct Node
*) ioreq2
);
1174 ioreq2
->ioir_Req
.io_Error
= IOERR_ABORTED
;
1175 ReplyMsg((struct Message
*) ioreq2
);
1176 ioreq2
= (struct IOIrDAReq
*) ncp
->ncp_ReadQueue
.lh_Head
;
1178 ioreq2
= (struct IOIrDAReq
*) ncp
->ncp_WriteQueue
.lh_Head
;
1179 while(ioreq2
->ioir_Req
.io_Message
.mn_Node
.ln_Succ
)
1181 Remove((struct Node
*) ioreq2
);
1182 ioreq2
->ioir_Req
.io_Error
= IOERR_ABORTED
;
1183 ReplyMsg((struct Message
*) ioreq2
);
1184 ioreq2
= (struct IOIrDAReq
*) ncp
->ncp_WriteQueue
.lh_Head
;
1186 ReplyMsg((struct Message
*) ioreq
);
1190 ioreq
->ioir_Req
.io_Error
= IOERR_NOCMD
;
1191 ReplyMsg((struct Message
*) ioreq
);
1195 ioreq
= (struct IOIrDAReq
*) ncp
->ncp_ReadQueue
.lh_Head
;
1196 while((!ncp
->ncp_ReadPending
) && ioreq
->ioir_Req
.io_Message
.mn_Node
.ln_Succ
)
1198 // don't try to switch baudrates, if a write request is pending with different baudrate
1199 if(ncp
->ncp_WritePending
)
1201 if(ncp
->ncp_WritePending
->ioir_Baud
!= ioreq
->ioir_Baud
)
1206 if(ioreq
->ioir_Baud
!= ncp
->ncp_BaudRate
)
1208 nSetBaudrate(ncp
, ioreq
->ioir_Baud
);
1210 if(ncp
->ncp_RBufRemain
)
1212 len
= ncp
->ncp_RBufRemain
;
1213 ncp
->ncp_RBufRemain
= nReceiveFrame(ncp
, &ncp
->ncp_ReadBuffer
[ncp
->ncp_RBufOffset
], ncp
->ncp_RBufRemain
);
1214 if(ncp
->ncp_RBufRemain
)
1216 // data not fully read -- wait for next request to arrive
1217 ncp
->ncp_RBufOffset
+= len
- ncp
->ncp_RBufRemain
;
1221 KPRINTF(1, ("Sending out read pipe...\n"));
1222 psdSendPipe(ncp
->ncp_EPInPipe
, ncp
->ncp_ReadBuffer
, DEFBUFFERSIZE
);
1223 ncp
->ncp_ReadPending
= ioreq
;
1226 //if(!ncp->ncp_ReadPending)
1228 mediabusycnt
= 10; // avoid infinite waits
1230 ioreq
= (struct IOIrDAReq
*) ncp
->ncp_WriteQueue
.lh_Head
;
1231 while((mediabusycnt
>= 10) && (!ncp
->ncp_WritePending
) && ioreq
->ioir_Req
.io_Message
.mn_Node
.ln_Succ
)
1233 // don't try to switch baudrates, if a read request is pending with different baudrate
1234 if(ncp
->ncp_ReadPending
)
1236 if(ncp
->ncp_ReadPending
->ioir_Baud
!= ioreq
->ioir_Baud
)
1241 Remove((struct Node
*) ioreq
);
1242 if(ioreq
->ioir_Baud
!= ncp
->ncp_BaudRate
)
1244 nSetBaudrate(ncp
, ioreq
->ioir_Baud
);
1246 if(!nSendFrame(ncp
, ioreq
))
1248 // an error occurred!
1249 ReplyMsg((struct Message
*) ioreq
);
1250 ioreq
= (struct IOIrDAReq
*) ncp
->ncp_WriteQueue
.lh_Head
;
1255 sigs
= Wait(sigmask
);
1256 } while(!(sigs
& SIGBREAKF_CTRL_C
));
1258 /* Now remove all requests still pending *anywhere* */
1259 ncp
->ncp_DenyRequests
= TRUE
;
1260 /* Current transfers */
1261 if(ncp
->ncp_ReadPending
)
1263 KPRINTF(1, ("Aborting pending read...\n"));
1264 psdAbortPipe(ncp
->ncp_EPInPipe
);
1265 psdWaitPipe(ncp
->ncp_EPInPipe
);
1266 ncp
->ncp_ReadPending
= NULL
;
1268 if((ioreq
= ncp
->ncp_WritePending
))
1270 KPRINTF(1, ("Aborting pending write...\n"));
1271 psdAbortPipe(ncp
->ncp_EPOutPipe
);
1272 psdWaitPipe(ncp
->ncp_EPOutPipe
);
1273 ncp
->ncp_WritePending
= NULL
;
1275 /* Read/Write queues */
1276 ioreq
= (struct IOIrDAReq
*) ncp
->ncp_WriteQueue
.lh_Head
;
1277 while(ioreq
->ioir_Req
.io_Message
.mn_Node
.ln_Succ
)
1279 KPRINTF(1, ("Removing write request...\n"));
1280 Remove((struct Node
*) ioreq
);
1281 ioreq
->ioir_Req
.io_Error
= IOERR_ABORTED
;
1282 ReplyMsg((struct Message
*) ioreq
);
1283 ioreq
= (struct IOIrDAReq
*) ncp
->ncp_WriteQueue
.lh_Head
;
1285 ioreq
= (struct IOIrDAReq
*) ncp
->ncp_ReadQueue
.lh_Head
;
1286 while(ioreq
->ioir_Req
.io_Message
.mn_Node
.ln_Succ
)
1288 KPRINTF(1, ("Removing read request...\n"));
1289 Remove((struct Node
*) ioreq
);
1290 ioreq
->ioir_Req
.io_Error
= IOERR_ABORTED
;
1291 ReplyMsg((struct Message
*) ioreq
);
1292 ioreq
= (struct IOIrDAReq
*) ncp
->ncp_ReadQueue
.lh_Head
;
1295 while((ioreq
= (struct IOIrDAReq
*) GetMsg(&ncp
->ncp_Unit
.unit_MsgPort
)))
1297 KPRINTF(1, ("Aborting pending requests...\n"));
1298 ioreq
->ioir_Req
.io_Error
= IOERR_ABORTED
;
1299 ReplyMsg((struct Message
*) ioreq
);
1302 KPRINTF(20, ("Going down the river!\n"));
1310 /* /// "nAllocSTIr4200()" */
1311 struct NepClassSTIr4200
* nAllocSTIr4200(void)
1313 struct Task
*thistask
;
1314 struct NepClassSTIr4200
*ncp
;
1316 thistask
= FindTask(NULL
);
1319 ncp
= thistask
->tc_UserData
;
1320 if(!(ncp
->ncp_Base
= OpenLibrary("poseidon.library", 4)))
1325 ncp
->ncp_Interface
= psdFindInterface(ncp
->ncp_Device
, NULL
, TAG_END
);
1326 if(!ncp
->ncp_Interface
)
1328 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
, "Interface missing!");
1331 ncp
->ncp_EPIn
= psdFindEndpoint(ncp
->ncp_Interface
, NULL
,
1333 EA_TransferType
, USEAF_BULK
,
1335 ncp
->ncp_EPOut
= psdFindEndpoint(ncp
->ncp_Interface
, NULL
,
1337 EA_TransferType
, USEAF_BULK
,
1339 if(!(ncp
->ncp_EPIn
&& ncp
->ncp_EPOut
))
1341 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
, "IN or OUT endpoint missing!");
1345 psdGetAttrs(PGA_ENDPOINT
, ncp
->ncp_EPIn
,
1346 EA_MaxPktSize
, &ncp
->ncp_EPInMaxPktSize
,
1349 ncp
->ncp_ReadPending
= NULL
;
1350 ncp
->ncp_WritePending
= NULL
;
1351 if(!(ncp
->ncp_ReadBuffer
= AllocVec(DEFBUFFERSIZE
, MEMF_PUBLIC
|MEMF_CLEAR
)))
1353 KPRINTF(1, ("Out of memory for read buffer\n"));
1356 if(!(ncp
->ncp_WriteBuffer
= AllocVec(DEFBUFFERSIZE
, MEMF_PUBLIC
|MEMF_CLEAR
)))
1358 KPRINTF(1, ("Out of memory for read buffer\n"));
1361 ncp
->ncp_Unit
.unit_MsgPort
.mp_SigBit
= AllocSignal(-1);
1362 ncp
->ncp_Unit
.unit_MsgPort
.mp_SigTask
= thistask
;
1363 ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Type
= NT_MSGPORT
;
1364 ncp
->ncp_Unit
.unit_MsgPort
.mp_Flags
= PA_SIGNAL
;
1366 if((ncp
->ncp_TaskMsgPort
= CreateMsgPort()))
1368 if((ncp
->ncp_EP0Pipe
= psdAllocPipe(ncp
->ncp_Device
, ncp
->ncp_TaskMsgPort
, NULL
)))
1370 if((ncp
->ncp_EPOutPipe
= psdAllocPipe(ncp
->ncp_Device
, ncp
->ncp_TaskMsgPort
, ncp
->ncp_EPOut
)))
1372 /* Turn off short packets */
1373 psdSetAttrs(PGA_PIPE
, ncp
->ncp_EPOutPipe
,
1374 PPA_NoShortPackets
, TRUE
,
1375 PPA_NakTimeout
, TRUE
,
1376 PPA_NakTimeoutTime
, 1000,
1378 if((ncp
->ncp_EPInPipe
= psdAllocPipe(ncp
->ncp_Device
, ncp
->ncp_TaskMsgPort
, ncp
->ncp_EPIn
)))
1380 /* Turn off short packets */
1381 psdSetAttrs(PGA_PIPE
, ncp
->ncp_EPInPipe
,
1382 PPA_NakTimeout
, FALSE
,
1383 PPA_AllowRuntPackets
, TRUE
,
1386 nSetBaudrate(ncp
, 9600);
1388 ncp
->ncp_Task
= thistask
;
1391 psdFreePipe(ncp
->ncp_EPOutPipe
);
1393 psdFreePipe(ncp
->ncp_EP0Pipe
);
1395 DeleteMsgPort(ncp
->ncp_TaskMsgPort
);
1397 FreeSignal((LONG
) ncp
->ncp_Unit
.unit_MsgPort
.mp_SigBit
);
1399 CloseLibrary(ncp
->ncp_Base
);
1400 if(ncp
->ncp_ReadBuffer
)
1402 FreeVec(ncp
->ncp_ReadBuffer
);
1403 ncp
->ncp_ReadBuffer
= NULL
;
1405 if(ncp
->ncp_WriteBuffer
)
1407 FreeVec(ncp
->ncp_WriteBuffer
);
1408 ncp
->ncp_WriteBuffer
= NULL
;
1411 ncp
->ncp_Task
= NULL
;
1412 if(ncp
->ncp_ReadySigTask
)
1414 Signal(ncp
->ncp_ReadySigTask
, 1L<<ncp
->ncp_ReadySignal
);
1420 /* /// "nFreeSTIr4200()" */
1421 void nFreeSTIr4200(struct NepClassSTIr4200
*ncp
)
1423 struct IOStdReq
*ioreq
;
1425 /* Disable the message port, messages may still be queued */
1426 ncp
->ncp_Unit
.unit_MsgPort
.mp_SigTask
= NULL
;
1427 ncp
->ncp_Unit
.unit_MsgPort
.mp_Flags
= PA_IGNORE
;
1428 FreeSignal((LONG
) ncp
->ncp_Unit
.unit_MsgPort
.mp_SigBit
);
1429 // get rid of all messages that still have appeared here
1430 while((ioreq
= (struct IOStdReq
*) GetMsg(&ncp
->ncp_Unit
.unit_MsgPort
)))
1432 ioreq
->io_Error
= IOERR_ABORTED
;
1433 ReplyMsg((struct Message
*) ioreq
);
1437 psdFreePipe(ncp
->ncp_EPInPipe
);
1438 psdFreePipe(ncp
->ncp_EPOutPipe
);
1439 psdFreePipe(ncp
->ncp_EP0Pipe
);
1441 if(ncp
->ncp_ReadBuffer
)
1443 FreeVec(ncp
->ncp_ReadBuffer
);
1444 ncp
->ncp_ReadBuffer
= NULL
;
1446 if(ncp
->ncp_WriteBuffer
)
1448 FreeVec(ncp
->ncp_WriteBuffer
);
1449 ncp
->ncp_WriteBuffer
= NULL
;
1452 DeleteMsgPort(ncp
->ncp_TaskMsgPort
);
1453 CloseLibrary(ncp
->ncp_Base
);
1455 ncp
->ncp_Task
= NULL
;
1456 if(ncp
->ncp_ReadySigTask
)
1458 Signal(ncp
->ncp_ReadySigTask
, 1L<<ncp
->ncp_ReadySignal
);
1463 /* /// "nSetReg()" */
1464 BOOL
nSetReg(struct NepClassSTIr4200
*ncp
, ULONG reg
, ULONG value
)
1467 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_VENDOR
|URTF_DEVICE
,
1468 USTR_WRITE_REG
, value
, reg
);
1469 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, NULL
, 0);
1472 KPRINTF(10, ("Writing reg %1lx with %02lx failed: %s (%ld)",
1474 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
));
1475 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) libname
,
1476 "Writing reg %1lx with %02lx failed: %s (%ld)",
1478 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
1485 /**************************************************************************/
1487 /* /// "nGUITask()" */
1488 AROS_UFH0(void, nGUITask
)
1492 struct Task
*thistask
;
1493 struct NepSTIr4200Base
*nh
;
1494 struct NepClassSTIr4200
*ncp
;
1495 struct PsdIFFContext
*pic
;
1497 thistask
= FindTask(NULL
);
1499 #define ps ncp->ncp_PsdBase
1500 #undef IntuitionBase
1501 #define IntuitionBase ncp->ncp_IntBase
1502 #undef MUIMasterBase
1503 #define MUIMasterBase ncp->ncp_MUIBase
1505 ncp
= thistask
->tc_UserData
;
1506 nh
= ncp
->ncp_ClsBase
;
1508 ++nh
->nh_Library
.lib_OpenCnt
;
1509 if(!(MUIMasterBase
= OpenLibrary(MUIMASTER_NAME
, MUIMASTER_VMIN
)))
1511 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
1512 nGUITaskCleanup(ncp
);
1516 if(!(IntuitionBase
= OpenLibrary("intuition.library", 39)))
1518 KPRINTF(10, ("Couldn't open intuition.library.\n"));
1519 nGUITaskCleanup(ncp
);
1522 if(!(ps
= OpenLibrary("poseidon.library", 4)))
1524 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
1525 nGUITaskCleanup(ncp
);
1529 ncp
->ncp_App
= ApplicationObject
,
1530 MUIA_Application_Title
, (IPTR
)libname
,
1531 MUIA_Application_Version
, (IPTR
)VERSION_STRING
,
1532 MUIA_Application_Copyright
, (IPTR
)"©2002-2009 Chris Hodges",
1533 MUIA_Application_Author
, (IPTR
)"Chris Hodges <chrisly@platon42.de>",
1534 MUIA_Application_Description
, (IPTR
)"Settings for the stir4200.class",
1535 MUIA_Application_Base
, (IPTR
)"STIR4200",
1536 MUIA_Application_HelpFile
, (IPTR
)"HELP:Poseidon.guide",
1537 MUIA_Application_Menustrip
, (IPTR
)MenustripObject
,
1538 Child
, (IPTR
)MenuObjectT((IPTR
)"Project"),
1539 Child
, (IPTR
)(ncp
->ncp_AboutMI
= MenuitemObject
,
1540 MUIA_Menuitem_Title
, (IPTR
)"About...",
1541 MUIA_Menuitem_Shortcut
, (IPTR
)"?",
1544 Child
, (IPTR
)MenuObjectT((IPTR
)"Settings"),
1545 Child
, (IPTR
)(ncp
->ncp_UseMI
= MenuitemObject
,
1546 MUIA_Menuitem_Title
, (IPTR
)"Save",
1547 MUIA_Menuitem_Shortcut
, (IPTR
)"S",
1549 Child
, (IPTR
)(ncp
->ncp_SetDefaultMI
= MenuitemObject
,
1550 MUIA_Menuitem_Title
, (IPTR
)"Save as Default",
1551 MUIA_Menuitem_Shortcut
, (IPTR
)"D",
1553 Child
, (IPTR
)MenuitemObject
,
1554 MUIA_Menuitem_Title
, (IPTR
)NM_BARLABEL
,
1556 Child
, (IPTR
)(ncp
->ncp_MUIPrefsMI
= MenuitemObject
,
1557 MUIA_Menuitem_Title
, (IPTR
)"MUI Settings",
1558 MUIA_Menuitem_Shortcut
, (IPTR
)"M",
1563 SubWindow
, (IPTR
)(ncp
->ncp_MainWindow
= WindowObject
,
1564 MUIA_Window_ID
, MAKE_ID('M','A','I','N'),
1565 MUIA_Window_Title
, (IPTR
)libname
,
1566 MUIA_HelpNode
, (IPTR
)libname
,
1568 WindowContents
, (IPTR
)VGroup
,
1569 Child
, (IPTR
)HGroup
, GroupFrameT((IPTR
)(ncp
->ncp_Device
? "Device Settings" : "Default Device Settings")),
1570 Child
, (IPTR
)HSpace(0),
1571 Child
, (IPTR
)ColGroup(2),
1572 Child
, (IPTR
)Label((IPTR
) "Autostart IrDA Stack:"),
1573 Child
, (IPTR
)HGroup
,
1574 Child
, (IPTR
)(ncp
->ncp_StackAutoObj
= ImageObject
, ImageButtonFrame
,
1575 MUIA_Background
, MUII_ButtonBack
,
1577 MUIA_InputMode
, MUIV_InputMode_Toggle
,
1578 MUIA_Image_Spec
, MUII_CheckMark
,
1579 MUIA_Image_FreeVert
, TRUE
,
1580 MUIA_Selected
, ncp
->ncp_CDC
->cdc_StackAuto
,
1581 MUIA_ShowSelState
, FALSE
,
1583 Child
, (IPTR
)HSpace(0),
1585 Child
, (IPTR
)Label((IPTR
) "Default " DEVNAME
" Unit:"),
1586 Child
, (IPTR
)(ncp
->ncp_UnitObj
= StringObject
,
1589 MUIA_String_AdvanceOnCR
, TRUE
,
1590 MUIA_String_Integer
, ncp
->ncp_CDC
->cdc_DefaultUnit
,
1591 MUIA_String_Accept
, (IPTR
)"0123456789",
1594 //Child, (IPTR)HSpace(0),
1596 Child
, (IPTR
)VSpace(0),
1597 Child
, (IPTR
)HGroup
,
1598 MUIA_Group_SameWidth
, TRUE
,
1599 Child
, (IPTR
)(ncp
->ncp_UseObj
= TextObject
, ButtonFrame
,
1600 MUIA_ShowMe
, (IPTR
)ncp
->ncp_Device
,
1601 MUIA_Background
, MUII_ButtonBack
,
1603 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1604 MUIA_Text_Contents
, (IPTR
)"\33c Save ",
1606 Child
, (IPTR
)(ncp
->ncp_SetDefaultObj
= TextObject
, ButtonFrame
,
1607 MUIA_Background
, MUII_ButtonBack
,
1609 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1610 MUIA_Text_Contents
, (IPTR
)(ncp
->ncp_Device
? "\33c Save as Default " : "\33c Save Defaults "),
1612 Child
, (IPTR
)(ncp
->ncp_CloseObj
= TextObject
, ButtonFrame
,
1613 MUIA_Background
, MUII_ButtonBack
,
1615 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1616 MUIA_Text_Contents
, (IPTR
)"\33c Use ",
1625 KPRINTF(10, ("Couldn't create application\n"));
1626 nGUITaskCleanup(ncp
);
1630 DoMethod(ncp
->ncp_MainWindow
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
1631 ncp
->ncp_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
1632 DoMethod(ncp
->ncp_UseObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1633 ncp
->ncp_App
, 2, MUIM_Application_ReturnID
, ID_STORE_CONFIG
);
1634 DoMethod(ncp
->ncp_SetDefaultObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1635 ncp
->ncp_App
, 2, MUIM_Application_ReturnID
, ID_DEF_CONFIG
);
1636 DoMethod(ncp
->ncp_CloseObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1637 ncp
->ncp_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
1639 DoMethod(ncp
->ncp_AboutMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1640 ncp
->ncp_App
, 2, MUIM_Application_ReturnID
, ID_ABOUT
);
1641 DoMethod(ncp
->ncp_UseMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1642 ncp
->ncp_App
, 2, MUIM_Application_ReturnID
, ID_STORE_CONFIG
);
1643 DoMethod(ncp
->ncp_SetDefaultMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1644 ncp
->ncp_App
, 2, MUIM_Application_ReturnID
, ID_DEF_CONFIG
);
1645 DoMethod(ncp
->ncp_MUIPrefsMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1646 ncp
->ncp_App
, 2, MUIM_Application_OpenConfigWindow
, 0);
1654 get(ncp
->ncp_App
, MUIA_Application_Iconified
, &iconify
);
1655 set(ncp
->ncp_MainWindow
, MUIA_Window_Open
, TRUE
);
1656 get(ncp
->ncp_MainWindow
, MUIA_Window_Open
, &isopen
);
1657 if(!(isopen
|| iconify
))
1659 nGUITaskCleanup(ncp
);
1665 retid
= DoMethod(ncp
->ncp_App
, MUIM_Application_NewInput
, &sigs
);
1669 case ID_STORE_CONFIG
:
1670 case MUIV_Application_ReturnID_Quit
:
1671 get(ncp
->ncp_UnitObj
, MUIA_String_Integer
, &ncp
->ncp_CDC
->cdc_DefaultUnit
);
1672 get(ncp
->ncp_StackAutoObj
, MUIA_Selected
, &ncp
->ncp_CDC
->cdc_StackAuto
);
1674 if(retid
== ID_DEF_CONFIG
)
1676 pic
= psdGetClsCfg(libname
);
1679 psdSetClsCfg(libname
, NULL
);
1680 pic
= psdGetClsCfg(libname
);
1684 if(psdAddCfgEntry(pic
, ncp
->ncp_CDC
))
1686 psdSaveCfgToDisk(NULL
, FALSE
);
1692 pic
= psdGetUsbDevCfg(libname
, ncp
->ncp_DevIDString
, NULL
);
1695 psdSetUsbDevCfg(libname
, ncp
->ncp_DevIDString
, NULL
, NULL
);
1696 pic
= psdGetUsbDevCfg(libname
, ncp
->ncp_DevIDString
, NULL
);
1700 if(psdAddCfgEntry(pic
, ncp
->ncp_CDC
))
1702 if(retid
!= MUIV_Application_ReturnID_Quit
)
1704 psdSaveCfgToDisk(NULL
, FALSE
);
1706 retid
= MUIV_Application_ReturnID_Quit
;
1710 retid
= MUIV_Application_ReturnID_Quit
;
1715 MUI_RequestA(ncp
->ncp_App
, ncp
->ncp_MainWindow
, 0, NULL
, "Blimey!", VERSION_STRING
, NULL
);
1718 if(retid
== MUIV_Application_ReturnID_Quit
)
1724 sigs
= Wait(sigs
| sigmask
| SIGBREAKF_CTRL_C
);
1725 if(sigs
& SIGBREAKF_CTRL_C
)
1731 set(ncp
->ncp_MainWindow
, MUIA_Window_Open
, FALSE
);
1733 nGUITaskCleanup(ncp
);
1739 /* /// "nGUITaskCleanup()" */
1740 void nGUITaskCleanup(struct NepClassSTIr4200
*ncp
)
1744 MUI_DisposeObject(ncp
->ncp_App
);
1745 ncp
->ncp_App
= NULL
;
1749 CloseLibrary(MUIMasterBase
);
1750 MUIMasterBase
= NULL
;
1754 CloseLibrary(IntuitionBase
);
1755 IntuitionBase
= NULL
;
1763 ncp
->ncp_GUIBinding
= NULL
;
1764 ncp
->ncp_GUITask
= NULL
;
1765 if(ncp
->ncp_ReadySigTask
)
1767 Signal(ncp
->ncp_ReadySigTask
, 1L<<ncp
->ncp_ReadySignal
);
1769 --ncp
->ncp_ClsBase
->nh_Library
.lib_OpenCnt
;