2 *----------------------------------------------------------------------------
3 * dfu class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
10 #include "dfu.class.h"
13 static const STRPTR libname
= MOD_NAME_STRING
;
15 static int libInit(LIBBASETYPEPTR nh
)
17 struct NepDFUBase
*ret
= NULL
;
19 KPRINTF(10, ("libInit nh: 0x%08lx SysBase: 0x%08lx\n", nh
, SysBase
));
21 nh
->nh_UtilityBase
= OpenLibrary("utility.library", 39);
23 #define UtilityBase nh->nh_UtilityBase
29 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
32 KPRINTF(10, ("libInit: Ok\n"));
33 return(ret
? TRUE
: FALSE
);
36 static int libExpunge(LIBBASETYPEPTR nh
)
38 KPRINTF(10, ("libExpunge nh: 0x%08lx\n", nh
));
39 CloseLibrary((struct Library
*) UtilityBase
);
43 ADD2INITLIB(libInit
, 0)
44 ADD2EXPUNGELIB(libExpunge
, 0)
48 * ***********************************************************************
49 * * Library functions *
50 * ***********************************************************************
53 /* /// "usbAttemptInterfaceBinding()" */
54 struct NepClassDFU
* usbAttemptInterfaceBinding(struct NepDFUBase
*nh
, struct PsdInterface
*pif
)
61 KPRINTF(1, ("nepDFUAttemptInterfaceBinding(%08lx)\n", pif
));
62 if((ps
= OpenLibrary("poseidon.library", 4)))
64 psdGetAttrs(PGA_INTERFACE
, pif
,
66 IFA_SubClass
, &subclass
,
71 if((ifclass
== FWUPGRADE_CLASSCODE
) && (subclass
== FWUPGRADE_STD_SUBCLASS
))
73 return(usbForceInterfaceBinding(nh
, pif
));
80 /* /// "usbForceInterfaceBinding()" */
81 struct NepClassDFU
* usbForceInterfaceBinding(struct NepDFUBase
*nh
, struct PsdInterface
*pif
)
84 struct NepClassDFU
*nch
;
87 struct PsdDevice
*hubpd
;
88 struct PsdDescriptor
*pdd
;
97 struct UsbDFUDesc
*dfudesc
= NULL
;
99 KPRINTF(1, ("nepDFUForceInterfaceBinding(%08lx)\n", pif
));
100 if((ps
= OpenLibrary("poseidon.library", 4)))
102 psdGetAttrs(PGA_INTERFACE
, pif
,
104 IFA_IDString
, &ifidstr
,
105 IFA_InterfaceNum
, &ifnum
,
106 IFA_Protocol
, &ifproto
,
108 psdGetAttrs(PGA_CONFIG
, pc
,
111 psdGetAttrs(PGA_DEVICE
, pd
,
112 DA_ProductName
, &devname
,
114 DA_ProductID
, &prodid
,
115 DA_IDString
, &devidstr
,
116 DA_HubDevice
, &hubpd
,
117 DA_AtHubPortNumber
, &hubport
,
119 pdd
= psdFindDescriptor(pd
, NULL
,
120 DDA_DescriptorType
, UDT_DFU
,
125 if((nch
= psdAllocVec(sizeof(struct NepClassDFU
))))
127 nch
->nch_ClsBase
= nh
;
128 nch
->nch_Device
= pd
;
129 nch
->nch_Hub
= hubpd
;
130 nch
->nch_HubPort
= hubport
;
131 nch
->nch_Interface
= pif
;
132 nch
->nch_DevIDString
= devidstr
;
133 nch
->nch_IfIDString
= ifidstr
;
134 nch
->nch_IfNum
= ifnum
;
136 psdGetAttrs(PGA_DESCRIPTOR
, pdd
,
137 DDA_DescriptorData
, &dfudesc
,
139 nch
->nch_WillDetach
= dfudesc
->bmAttributes
& UDDAF_WILL_DETACH
;
140 nch
->nch_CanUpgrade
= dfudesc
->bmAttributes
& UDDAF_DOWNLOADABLE
;
141 nch
->nch_CanRetrieve
= dfudesc
->bmAttributes
& UDDAF_UPLOADABLE
;
142 nch
->nch_NoManifestReset
= dfudesc
->bmAttributes
& UDDAF_NO_MANIFEST_RST
;
144 nch
->nch_DetachTimeOut
= dfudesc
->wDetachTimeOut0
|(dfudesc
->wDetachTimeOut1
<<8);
145 nch
->nch_TransferSize
= dfudesc
->wTransferSize0
|(dfudesc
->wTransferSize1
<<8);
147 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
148 "Firmware %s available for '%s' (through config GUI)!",
149 ((nch
->nch_CanUpgrade
&& nch
->nch_CanRetrieve
) ? "Download/Upgrade" :
150 (nch
->nch_CanRetrieve
? "Download" :
151 (nch
->nch_CanUpgrade
? "Upgrade" : "Cage"))),
154 if((prodid
== 0xffff) || (devclass
== FWUPGRADE_CLASSCODE
) || (ifproto
== FWUPGRADE_PROTO_DFU
))
156 nOpenBindingCfgWindow(nh
, nch
);
162 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
,
163 "Could not find DFU functional descriptor for '%s'!",
173 /* /// "usbReleaseInterfaceBinding()" */
174 void usbReleaseInterfaceBinding(struct NepDFUBase
*nh
, struct NepClassDFU
*nch
)
177 struct PsdConfig
*pc
;
178 struct PsdDevice
*pd
;
181 KPRINTF(1, ("nepDFUReleaseInterfaceBinding(%08lx)\n", nch
));
182 if((ps
= OpenLibrary("poseidon.library", 4)))
185 nch
->nch_ReadySignal
= SIGB_SINGLE
;
186 nch
->nch_ReadySigTask
= FindTask(NULL
);
189 Signal(nch
->nch_GUITask
, SIGBREAKF_CTRL_C
);
192 while(nch
->nch_GUITask
)
194 Wait(1L<<nch
->nch_ReadySignal
);
197 //FreeSignal(nch->nch_ReadySignal);
198 psdGetAttrs(PGA_INTERFACE
, nch
->nch_Interface
, IFA_Config
, &pc
, TAG_END
);
199 psdGetAttrs(PGA_CONFIG
, pc
, CA_Device
, &pd
, TAG_END
);
200 psdGetAttrs(PGA_DEVICE
, pd
, DA_ProductName
, &devname
, TAG_END
);
201 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
202 "Lost firm grip on '%s'!",
210 /* /// "usbGetAttrsA()" */
211 AROS_LH3(LONG
, usbGetAttrsA
,
212 AROS_LHA(ULONG
, type
, D0
),
213 AROS_LHA(APTR
, usbstruct
, A0
),
214 AROS_LHA(struct TagItem
*, tags
, A1
),
215 LIBBASETYPEPTR
, nh
, 5, nep
)
222 KPRINTF(1, ("nepDFUGetAttrsA(%ld, %08lx, %08lx)\n", type
, usbstruct
, tags
));
226 if((ti
= FindTagItem(UCCA_Priority
, tags
)))
228 *((SIPTR
*) ti
->ti_Data
) = -100;
231 if((ti
= FindTagItem(UCCA_Description
, tags
)))
233 *((STRPTR
*) ti
->ti_Data
) = "Firmware Upgrading/Downloading";
236 if((ti
= FindTagItem(UCCA_HasClassCfgGUI
, tags
)))
238 *((IPTR
*) ti
->ti_Data
) = FALSE
;
241 if((ti
= FindTagItem(UCCA_HasBindingCfgGUI
, tags
)))
243 *((IPTR
*) ti
->ti_Data
) = TRUE
;
246 if((ti
= FindTagItem(UCCA_AfterDOSRestart
, tags
)))
248 *((IPTR
*) ti
->ti_Data
) = FALSE
;
251 if((ti
= FindTagItem(UCCA_UsingDefaultCfg
, tags
)))
253 *((IPTR
*) ti
->ti_Data
) = TRUE
;
259 if((ti
= FindTagItem(UCBA_UsingDefaultCfg
, tags
)))
261 *((IPTR
*) ti
->ti_Data
) = TRUE
;
271 /* /// "usbSetAttrsA()" */
272 AROS_LH3(LONG
, usbSetAttrsA
,
273 AROS_LHA(ULONG
, type
, D0
),
274 AROS_LHA(APTR
, usbstruct
, A0
),
275 AROS_LHA(struct TagItem
*, tags
, A1
),
276 LIBBASETYPEPTR
, nh
, 6, nep
)
284 /* /// "usbDoMethodA()" */
285 AROS_LH2(IPTR
, usbDoMethodA
,
286 AROS_LHA(ULONG
, methodid
, D0
),
287 AROS_LHA(IPTR
*, methoddata
, A1
),
288 LIBBASETYPEPTR
, nh
, 7, nep
)
292 KPRINTF(10, ("Do Method %ld\n", methodid
));
295 case UCM_AttemptInterfaceBinding
:
296 return((IPTR
) usbAttemptInterfaceBinding(nh
, (struct PsdInterface
*) methoddata
[0]));
298 case UCM_ForceInterfaceBinding
:
299 return((IPTR
) usbForceInterfaceBinding(nh
, (struct PsdInterface
*) methoddata
[0]));
301 case UCM_ReleaseInterfaceBinding
:
302 usbReleaseInterfaceBinding(nh
, (struct NepClassDFU
*) methoddata
[0]);
305 case UCM_OpenCfgWindow
:
308 case UCM_OpenBindingCfgWindow
:
309 return(nOpenBindingCfgWindow(nh
, (struct NepClassDFU
*) methoddata
[0]));
311 case UCM_ConfigChangedEvent
:
322 /* /// "nOpenBindingCfgWindow()" */
323 LONG
nOpenBindingCfgWindow(struct NepDFUBase
*nh
, struct NepClassDFU
*nch
)
326 KPRINTF(10, ("Opening GUI...\n"));
327 if(!(ps
= OpenLibrary("poseidon.library", 4)))
332 if(!nch
->nch_GUITask
)
334 if((nch
->nch_GUITask
= psdSpawnSubTask(MOD_NAME_STRING
" GUI", nGUITask
, nch
)))
347 /**************************************************************************/
351 const STRPTR DFUErrors
[] =
353 "No error condition is present.",
354 "File is not targeted for use by this device.",
355 "File is for this device but fails some vendor-specific verification test.",
356 "Device is unable to write memory.",
357 "Memory erase function failed.",
358 "Memory erase check failed.",
359 "Program memory function failed.",
360 "Programmed memory failed verification.",
361 "Cannot program memory due to received address that is out of range.",
362 "Received DFU_DNLOAD with wLength = 0, but device does not think it has all of the data yet.",
363 "Device's firmware is corrupt. It cannot return to run-time (non-DFU) operations.",
364 "iString indicates a vendor-specific error.",
365 "Device detected unexpected USB reset signaling.",
366 "Device detected unexpected power on reset.",
367 "Something went wrong, but the device does not know what it was.",
368 "Device stalled an unexpected request."
371 const STRPTR DFUStates
[] =
373 "Device is running its normal application.",
374 "Transition from normal to DFU mode.",
375 "Device is operating in the DFU mode.",
376 "Device has received a block, waiting for GetStatus.",
377 "Device is programming a block into its memories.",
378 "Device is processing a download operation.",
379 "Device has received the final block of firmware.",
380 "Device is in the Manifestation phase.",
381 "Device is waiting for reset.",
382 "Device is processing an upload operation.",
383 "An error has occurred."
386 /* /// "nGUITask()" */
387 AROS_UFH0(void, nGUITask
)
391 struct Task
*thistask
;
392 struct NepDFUBase
*nh
;
393 struct NepClassDFU
*nch
;
394 BOOL initokay
= FALSE
;
397 thistask
= FindTask(NULL
);
399 #define ps nch->nch_PsdBase
401 #define IntuitionBase nch->nch_IntBase
403 #define MUIMasterBase nch->nch_MUIBase
405 #define DOSBase nch->nch_DOSBase
407 nch
= thistask
->tc_UserData
;
408 nh
= nch
->nch_ClsBase
;
410 ++nh
->nh_Library
.lib_OpenCnt
;
413 if(!(MUIMasterBase
= OpenLibrary(MUIMASTER_NAME
, MUIMASTER_VMIN
)))
415 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
419 if(!(IntuitionBase
= OpenLibrary("intuition.library", 39)))
421 KPRINTF(10, ("Couldn't open intuition.library.\n"));
424 if(!(DOSBase
= OpenLibrary("dos.library", 39)))
426 KPRINTF(10, ("Couldn't open dos.library.\n"));
429 if(!(ps
= OpenLibrary("poseidon.library", 4)))
431 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
434 if(!(nch
->nch_TaskMsgPort
= CreateMsgPort()))
438 if(!(nch
->nch_EP0Pipe
= psdAllocPipe(nch
->nch_Device
, nch
->nch_TaskMsgPort
, NULL
)))
442 psdSetAttrs(PGA_PIPE
, nch
->nch_EP0Pipe
,
443 PPA_NakTimeout
, TRUE
,
444 PPA_NakTimeoutTime
, 15000,
447 if(!(nch
->nch_Buffer
= psdAllocVec(nch
->nch_TransferSize
)))
455 nGUITaskCleanup(nch
);
460 infomsg
= nGetStatus(nch
);
462 nch
->nch_App
= ApplicationObject
,
463 MUIA_Application_Title
, (IPTR
)libname
,
464 MUIA_Application_Version
, (IPTR
)VERSION_STRING
,
465 MUIA_Application_Copyright
, (IPTR
)"©2005-2009 Chris Hodges",
466 MUIA_Application_Author
, (IPTR
)"Chris Hodges <chrisly@platon42.de>",
467 MUIA_Application_Description
, (IPTR
)"Settings for the dfu.class",
468 MUIA_Application_Base
, (IPTR
)"DFU",
469 MUIA_Application_HelpFile
, (IPTR
)"HELP:Poseidon.guide",
470 MUIA_Application_Menustrip
, (IPTR
)MenustripObject
,
471 Child
, (IPTR
)MenuObjectT((IPTR
)"Project"),
472 Child
, (IPTR
)(nch
->nch_AboutMI
= MenuitemObject
,
473 MUIA_Menuitem_Title
, (IPTR
)"About...",
474 MUIA_Menuitem_Shortcut
, (IPTR
)"?",
477 Child
, (IPTR
)MenuObjectT((IPTR
)"Settings"),
478 Child
, (IPTR
)(nch
->nch_MUIPrefsMI
= MenuitemObject
,
479 MUIA_Menuitem_Title
, (IPTR
)"MUI Settings",
480 MUIA_Menuitem_Shortcut
, (IPTR
)"M",
485 SubWindow
, (IPTR
)(nch
->nch_MainWindow
= WindowObject
,
486 MUIA_Window_ID
, MAKE_ID('M','A','I','N'),
487 MUIA_Window_Title
, (IPTR
)libname
,
488 MUIA_HelpNode
, (IPTR
)libname
,
490 WindowContents
, (IPTR
)VGroup
,
491 Child
, (IPTR
)VGroup
, GroupFrameT((IPTR
)"Firmware Upgrade/Download"),
493 MUIA_ShowMe
, nch
->nch_DFUStatus
.bState
>= STATE_DFU_IDLE
,
494 Child
, (IPTR
)Label((IPTR
) "Firmware file:"),
495 Child
, (IPTR
)PopaslObject
,
496 MUIA_Popstring_String
, (IPTR
)(nch
->nch_FWFileObj
= StringObject
,
499 MUIA_String_AdvanceOnCR
, TRUE
,
500 MUIA_String_MaxLen
, 256,
502 MUIA_Popstring_Button
, (IPTR
)PopButton(MUII_PopFile
),
503 ASLFR_TitleText
, (IPTR
)"Select a firmware binary file...",
504 ASLFR_InitialPattern
, (IPTR
)"#?.dfu",
505 ASLFR_DoPatterns
, TRUE
,
508 Child
, (IPTR
)(nch
->nch_GaugeObj
= GaugeObject
,
509 MUIA_Frame
, MUIV_Frame_ReadList
,
510 MUIA_Gauge_Horiz
, TRUE
,
511 MUIA_Gauge_InfoText
, (IPTR
)infomsg
,
512 MUIA_Gauge_Current
, 0,
516 MUIA_Group_SameWidth
, TRUE
,
517 Child
, (IPTR
)(nch
->nch_DetachObj
= TextObject
, ButtonFrame
,
518 MUIA_ShowMe
, !nch
->nch_DFUStatus
.bState
,
519 MUIA_Background
, MUII_ButtonBack
,
521 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
522 MUIA_Text_Contents
, (IPTR
)"\33c Enter DFU Mode ",
524 Child
, (IPTR
)(nch
->nch_DownloadObj
= TextObject
, ButtonFrame
,
525 MUIA_ShowMe
, nch
->nch_DFUStatus
.bState
>= STATE_DFU_IDLE
,
526 MUIA_Disabled
, !nch
->nch_CanRetrieve
,
527 MUIA_Background
, MUII_ButtonBack
,
529 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
530 MUIA_Text_Contents
, (IPTR
)"\33c Download (Read) ",
532 Child
, (IPTR
)(nch
->nch_UploadObj
= TextObject
, ButtonFrame
,
533 MUIA_ShowMe
, nch
->nch_DFUStatus
.bState
>= STATE_DFU_IDLE
,
534 MUIA_Disabled
, !nch
->nch_CanUpgrade
,
535 MUIA_Background
, MUII_ButtonBack
,
537 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
538 MUIA_Text_Contents
, (IPTR
)"\33c Upgrade (Write) ",
542 Child
, (IPTR
)VSpace(0),
543 Child
, (IPTR
)(nch
->nch_CloseObj
= TextObject
, ButtonFrame
,
544 MUIA_Background
, MUII_ButtonBack
,
546 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
547 MUIA_Text_Contents
, (IPTR
)"\33c Close ",
555 KPRINTF(10, ("Couldn't create application\n"));
556 nGUITaskCleanup(nch
);
560 DoMethod(nch
->nch_MainWindow
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
561 nch
->nch_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
562 DoMethod(nch
->nch_DetachObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
563 nch
->nch_App
, 2, MUIM_Application_ReturnID
, ID_DETACH
);
564 DoMethod(nch
->nch_DownloadObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
565 nch
->nch_App
, 2, MUIM_Application_ReturnID
, ID_DOWNLOAD
);
566 DoMethod(nch
->nch_UploadObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
567 nch
->nch_App
, 2, MUIM_Application_ReturnID
, ID_UPLOAD
);
568 DoMethod(nch
->nch_CloseObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
569 nch
->nch_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
571 DoMethod(nch
->nch_AboutMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
572 nch
->nch_App
, 2, MUIM_Application_ReturnID
, ID_ABOUT
);
573 DoMethod(nch
->nch_MUIPrefsMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
574 nch
->nch_App
, 2, MUIM_Application_OpenConfigWindow
, 0);
582 get(nch
->nch_App
, MUIA_Application_Iconified
, &iconify
);
583 set(nch
->nch_MainWindow
, MUIA_Window_Open
, TRUE
);
584 get(nch
->nch_MainWindow
, MUIA_Window_Open
, &isopen
);
585 if(!(isopen
|| iconify
))
587 nGUITaskCleanup(nch
);
593 retid
= DoMethod(nch
->nch_App
, MUIM_Application_NewInput
, &sigs
);
609 MUI_RequestA(nch
->nch_App
, nch
->nch_MainWindow
, 0, NULL
, "Blimey!", VERSION_STRING
, NULL
);
612 if(retid
== MUIV_Application_ReturnID_Quit
)
618 sigs
= Wait(sigs
| sigmask
| SIGBREAKF_CTRL_C
);
619 if(sigs
& SIGBREAKF_CTRL_C
)
625 set(nch
->nch_MainWindow
, MUIA_Window_Open
, FALSE
);
627 nGUITaskCleanup(nch
);
633 /* /// "nDetach()" */
634 void nDetach(struct NepClassDFU
*nch
)
636 ULONG delay
= (nch
->nch_DetachTimeOut
< 2000) ? nch
->nch_DetachTimeOut
: 2000;
639 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_CLASS
|URTF_INTERFACE
,
640 UDFUR_DETACH
, delay
, nch
->nch_IfNum
);
641 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, NULL
, 0);
644 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) libname
,
645 "Detaching failed: %s (%ld)",
646 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
649 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, nGetStatus(nch
));
650 if(!nch
->nch_WillDetach
)
652 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
653 "Sending USB Reset to device...");
655 psdDelayMS(delay
>>1);
656 psdDoHubMethod(nch
->nch_Device
, UCM_HubPowerCyclePort
, nch
->nch_Hub
, nch
->nch_HubPort
);
658 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
659 "Waiting for device to detach automatically...");
664 /* /// "nFWDownload()" */
665 void nFWDownload(struct NepClassDFU
*nch
)
668 CONST_STRPTR file
= "";
672 get(nch
->nch_FWFileObj
, MUIA_String_Contents
, &file
);
675 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, "Give filename for writing!");
678 if((nch
->nch_InOutFile
= Open(file
, MODE_NEWFILE
)))
680 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, "Starting download...");
683 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_IN
|URTF_CLASS
|URTF_INTERFACE
,
684 UDFUR_UPLOAD
, (ULONG
) blocknum
, nch
->nch_IfNum
);
685 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, nch
->nch_Buffer
, nch
->nch_TransferSize
);
686 len
= psdGetPipeActual(nch
->nch_EP0Pipe
);
687 if((!ioerr
) || (ioerr
== UHIOERR_RUNTPACKET
))
689 /*psdAddErrorMsg(RETURN_ERROR, (STRPTR) libname,
691 Write(nch
->nch_InOutFile
, nch
->nch_Buffer
, len
);
693 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) libname
,
694 "Download at block %ld failed: %s (%ld), %ld read",
696 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
, len
);
698 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, nGetStatus(nch
));
702 set(nch
->nch_GaugeObj
, MUIA_Gauge_Current
, blocknum
% 100);
704 set(nch
->nch_GaugeObj
, MUIA_Gauge_Current
, 0);
705 if(ioerr
== UHIOERR_RUNTPACKET
)
707 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, "Finished downloading.");
709 Close(nch
->nch_InOutFile
);
711 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, "Error opening file!");
716 /* /// "nFWUpload()" */
717 void nFWUpload(struct NepClassDFU
*nch
)
720 CONST_STRPTR file
= "";
729 get(nch
->nch_FWFileObj
, MUIA_String_Contents
, &file
);
732 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, "Give firmware file!");
735 if((nch
->nch_InOutFile
= Open(file
, MODE_OLDFILE
)))
737 Seek(nch
->nch_InOutFile
, 0, OFFSET_END
);
738 totallen
= Seek(nch
->nch_InOutFile
, 0, OFFSET_BEGINNING
);
739 choice
= MUI_Request(nch
->nch_App
, nch
->nch_MainWindow
, 0, NULL
, "Continue|Cancel",
740 "Are you sure you want to reflash the firmware of this device?\n\n"
741 "\33bDO NOT REMOVE THE DEVICE OR REBOOT DURING THIS PROCESS!\33n\n"
742 "This might render the device useless!\n", NULL
);
745 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, "Starting upload...");
746 set(nch
->nch_GaugeObj
, MUIA_Gauge_Max
, totallen
);
749 KPRINTF(1, ("Reading %ld/%ld: %ld...\n", pos
, totallen
, nch
->nch_TransferSize
));
750 len
= Read(nch
->nch_InOutFile
, nch
->nch_Buffer
, nch
->nch_TransferSize
);
756 set(nch
->nch_GaugeObj
, MUIA_Gauge_Current
, pos
);
757 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_CLASS
|URTF_INTERFACE
,
758 UDFUR_DNLOAD
, (ULONG
) blocknum
, nch
->nch_IfNum
);
759 KPRINTF(1, ("Sending %ld\n", len
));
760 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, nch
->nch_Buffer
, len
);
761 KPRINTF(1, ("IOErr = %ld\n", ioerr
));
764 infomsg
= nGetStatus(nch
);
765 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, infomsg
);
766 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) libname
,
767 "Upload at block %ld failed: %s (%ld), %s",
769 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
, infomsg
);
772 infomsg
= nGetStatus(nch
);
773 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, infomsg
);
774 if(nch
->nch_DFUStatus
.bState
== STATE_DFU_ERROR
)
776 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) libname
,
777 "Upload at block %ld failed: %s",
782 delay
= nch
->nch_DFUStatus
.bwPollTimeout0
|(nch
->nch_DFUStatus
.bwPollTimeout1
<<8)|(nch
->nch_DFUStatus
.bwPollTimeout2
<<16);
783 KPRINTF(1, ("Delaying %ldms\n", delay
));
784 //psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "Delaying %ldms", delay);
789 } while((!ioerr
) && len
);
790 KPRINTF(1, ("Done\n"));
791 set(nch
->nch_GaugeObj
, MUIA_Gauge_Current
, 0);
792 set(nch
->nch_GaugeObj
, MUIA_Gauge_Max
, 100);
796 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, "Finished uploading, manifesting.");
797 if(nch
->nch_NoManifestReset
)
800 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, nGetStatus(nch
));
802 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
803 "Sending USB Reset to device in 5 seconds...");
806 //psdDoHubMethod(nch->nch_Device, UCM_HubPowerCyclePort, nch->nch_Hub, nch->nch_HubPort);
807 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, nGetStatus(nch
));
811 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, "Upgrade aborted by user.");
813 Close(nch
->nch_InOutFile
);
815 set(nch
->nch_GaugeObj
, MUIA_Gauge_InfoText
, "Error opening file!");
820 /* /// "nGetStatus()" */
821 STRPTR
nGetStatus(struct NepClassDFU
*nch
)
826 KPRINTF(1, ("GetStatus\n"));
827 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_IN
|URTF_CLASS
|URTF_INTERFACE
,
828 UDFUR_GETSTATUS
, 0, nch
->nch_IfNum
);
829 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, &nch
->nch_DFUStatus
, sizeof(nch
->nch_DFUStatus
));
832 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) libname
,
833 "UDFUR_GETSTATUS failed: %s (%ld)",
834 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
835 nch
->nch_DFUStatus
.bState
= STATE_DFU_ERROR
;
836 nch
->nch_DFUStatus
.bStatus
= STATUS_ERR_UNKNOWN
;
838 KPRINTF(1, ("State %ld, Status %ld\n", nch
->nch_DFUStatus
.bState
, nch
->nch_DFUStatus
.bStatus
));
839 if(nch
->nch_DFUStatus
.bState
> STATE_DFU_ERROR
)
841 nch
->nch_DFUStatus
.bState
= STATE_DFU_ERROR
;
843 if(nch
->nch_DFUStatus
.bStatus
> STATUS_ERR_STALLEDPKT
)
845 nch
->nch_DFUStatus
.bStatus
= STATUS_ERR_UNKNOWN
;
848 if(nch
->nch_DFUStatus
.bState
== STATE_DFU_ERROR
)
850 infomsg
= DFUErrors
[nch
->nch_DFUStatus
.bStatus
];
851 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_CLASS
|URTF_INTERFACE
,
852 UDFUR_CLRSTATUS
, 0, nch
->nch_IfNum
);
853 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, NULL
, 0);
856 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) libname
,
857 "UDFUR_CLRSTATUS failed: %s (%ld)",
858 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
861 infomsg
= DFUStates
[nch
->nch_DFUStatus
.bState
];
867 /* /// "nGUITaskCleanup()" */
868 void nGUITaskCleanup(struct NepClassDFU
*nch
)
872 MUI_DisposeObject(nch
->nch_App
);
877 psdFreeVec(nch
->nch_Buffer
);
878 nch
->nch_Buffer
= NULL
;
882 psdFreePipe(nch
->nch_EP0Pipe
);
883 nch
->nch_EP0Pipe
= NULL
;
885 if(nch
->nch_TaskMsgPort
)
887 DeleteMsgPort(nch
->nch_TaskMsgPort
);
888 nch
->nch_TaskMsgPort
= NULL
;
892 CloseLibrary(MUIMasterBase
);
893 MUIMasterBase
= NULL
;
897 CloseLibrary(DOSBase
);
902 CloseLibrary(IntuitionBase
);
903 IntuitionBase
= NULL
;
911 nch
->nch_GUIBinding
= NULL
;
912 nch
->nch_GUITask
= NULL
;
913 if(nch
->nch_ReadySigTask
)
915 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
917 --nch
->nch_ClsBase
->nh_Library
.lib_OpenCnt
;