2 Copyright © 2011, The AROS Development Team. All rights reserved
6 #include LC_LIBDEFS_FILE
8 #include "pciehci_uhw.h"
10 UWORD
cmdQueryDevice(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
);
11 UWORD
cmdReset(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
);
12 UWORD
cmdUsbReset(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
);
13 UWORD
cmdUsbResume(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
);
14 UWORD
cmdUsbSuspend(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
);
15 UWORD
cmdUsbOper(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
);
18 static int Open(LIBBASETYPEPTR LIBBASE
, struct IOUsbHWReq
*ioreq
, ULONG unit
, ULONG flags
) {
19 LIBBASETYPE
*ehd
= (LIBBASETYPE
*) LIBBASE
;
21 KPRINTF2(DBL_DEVIO
,("EHC Open: "));
23 if(ioreq
->iouh_Req
.io_Message
.mn_Length
< sizeof(struct IOUsbHWReq
)) {
24 KPRINTF2(DBL_DEVIO
, ("Invalid MN_LENGTH"));
25 ioreq
->iouh_Req
.io_Error
= IOERR_BADLENGTH
;
27 ioreq
->iouh_Req
.io_Error
= IOERR_OPENFAIL
;
29 struct Unitnode
*ehu_unitnode
;
30 ForeachNode(&ehd
->ehd_unitnodelist
, ehu_unitnode
) {
32 struct ehu_unit
*ehu
= (struct ehu_unit
*)ehu_unitnode
->ehu_unitptr
;
33 if(ehu
->ehu_unitnumber
== unit
) {
34 ioreq
->iouh_Req
.io_Unit
= (struct Unit
*)ehu
;
36 if(ehu
->ehu_devunit
.unit_OpenCnt
) {
37 ioreq
->iouh_Req
.io_Error
= IOERR_UNITBUSY
;
38 KPRINTF2(DBL_DEVIO
, ("Unit %ld already open", unit
));
41 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_REPLYMSG
;
42 ioreq
->iouh_Req
.io_Error
= 0;
43 ehu
->ehu_devunit
.unit_OpenCnt
++;
44 KPRINTF2(DBL_DEVIO
, ("Unit %ld opened\n", unit
));
50 KPRINTF2(DBL_DEVIO
, ("Unit %ld does not exist", unit
));
53 KPRINTF2(DBL_DEVIO
, (", could not open unit!\n"));
54 ioreq
->iouh_Req
.io_Unit
= NULL
;
58 static int Close(LIBBASETYPEPTR LIBBASE
, struct IOUsbHWReq
*ioreq
) {
59 // LIBBASETYPE *ehd = (LIBBASETYPE *) LIBBASE;
61 KPRINTF2(DBL_DEVIO
,("EHC Close: \n"));
63 struct ehu_unit
*ehu
= (struct ehu_unit
*) ioreq
->iouh_Req
.io_Unit
;
64 ehu
->ehu_devunit
.unit_OpenCnt
--;
69 AROS_LH1(void, BeginIO
, AROS_LHA(struct IOUsbHWReq
*, ioreq
, A1
), LIBBASETYPEPTR
, LIBBASE
, 5, pciehci
) {
72 LIBBASETYPE
*ehd
= (LIBBASETYPE
*) LIBBASE
;
74 KPRINTF2(DBL_DEVIO
,("EHC BeginIO: "));
76 struct ehu_unit
*ehu
= (struct ehu_unit
*) ioreq
->iouh_Req
.io_Unit
;
80 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_MESSAGE
;
81 ioreq
->iouh_Req
.io_Error
= UHIOERR_NO_ERROR
;
83 if (ioreq
->iouh_Req
.io_Command
< NSCMD_DEVICEQUERY
) {
84 switch (ioreq
->iouh_Req
.io_Command
) {
86 KPRINTF2(DBL_DEVIO
,("cmdReset\n"));
87 ret
= cmdReset(ioreq
, ehu
, ehd
);
91 KPRINTF2(DBL_DEVIO
,("cmdFlush\n"));
92 // ret = cmdFlush(ioreq, ehu, ehd);
95 case UHCMD_QUERYDEVICE
:
96 KPRINTF2(DBL_DEVIO
,("cmdQueryDevice\n"));
97 ret
= cmdQueryDevice(ioreq
, ehu
, ehd
);
101 KPRINTF2(DBL_DEVIO
,("cmdUsbReset\n"));
102 ret
= cmdUsbReset(ioreq
, ehu
, ehd
);
105 case UHCMD_USBRESUME
:
106 KPRINTF2(DBL_DEVIO
,("cmdUsbResume\n"));
107 ret
= cmdUsbResume(ioreq
, ehu
, ehd
);
110 case UHCMD_USBSUSPEND
:
111 KPRINTF2(DBL_DEVIO
,("cmdUsbSuspend\n"));
112 ret
= cmdUsbSuspend(ioreq
, ehu
, ehd
);
116 KPRINTF2(DBL_DEVIO
,("cmdUsbOper\n"));
117 ret
= cmdUsbOper(ioreq
, ehu
, ehd
);
120 case UHCMD_CONTROLXFER
:
121 KPRINTF2(DBL_DEVIO
,("cmdControlXFer\n"));
122 // ret = cmdControlXFer(ioreq, ehu, ehd);
126 KPRINTF2(DBL_DEVIO
,("cmdBulkXFer\n"));
127 // ret = cmdBulkXFer(ioreq, ehu, ehd);
131 KPRINTF2(DBL_DEVIO
,("cmdIntXFer\n"));
132 // ret = cmdIntXFer(ioreq, ehu, ehd);
136 KPRINTF2(DBL_DEVIO
,("cmdIsoXFer\n"));
137 // ret = cmdIsoXFer(ioreq, ehu, ehd);
141 KPRINTF2(DBL_DEVIO
,("IOERR_NOCMD\n"));
146 switch(ioreq
->iouh_Req
.io_Command
) {
147 case NSCMD_DEVICEQUERY
:
148 KPRINTF2(DBL_DEVIO
,("cmdNSDeviceQuery\n"));
150 struct NSDeviceQueryResult
*nsdq
= (struct NSDeviceQueryResult
*)((struct IOStdReq
*)(ioreq
))->io_Data
;
151 nsdq
->DevQueryFormat
= 0;
152 nsdq
->SizeAvailable
= sizeof(struct NSDeviceQueryResult
);
153 nsdq
->DeviceType
= NSDEVTYPE_USBHARDWARE
;
154 nsdq
->DeviceSubType
= 0;
155 nsdq
->SupportedCommands
= (UWORD
*)NSDSupported
;
162 KPRINTF2(DBL_DEVIO
,("IOERR_NOCMD\n"));
168 if(ret
!= RC_DONTREPLY
) {
169 /* Set error codes */
171 ioreq
->iouh_Req
.io_Error
= ret
& 0xff;
173 /* Terminate the iorequest */
174 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_FREEMSG
;
175 /* If not quick I/O, reply the message */
176 if(!(ioreq
->iouh_Req
.io_Flags
& IOF_QUICK
)) {
177 ReplyMsg(&ioreq
->iouh_Req
.io_Message
);
184 AROS_LH1(LONG
, AbortIO
, AROS_LHA(struct IOUsbHWReq
*, ioreq
, A1
), LIBBASETYPEPTR
, LIBBASE
, 6, pciehci
) {
187 // LIBBASETYPE *ehd = (LIBBASETYPE *) LIBBASE;
189 KPRINTF2(DBL_DEVIO
,("EHC AbortIO: \n"));
195 UWORD
cmdQueryDevice(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
) {
196 LIBBASETYPE
*ehd
= (LIBBASETYPE
*) LIBBASE
;
198 struct TagItem
*taglist
= (struct TagItem
*) ioreq
->iouh_Data
;
202 KPRINTF2(DBL_UHWIO
, ("EHC UHCMD_QUERYDEVICE: 0x%p, taglist: 0x%p\n", ioreq
, taglist
));
204 if((tag
= FindTagItem(UHA_State
, taglist
))) {
205 *((ULONG
*) tag
->ti_Data
) = (ULONG
) uhwGetUsbState(ioreq
, ehu
, ehd
);
209 if((tag
= FindTagItem(UHA_Manufacturer
, taglist
))) {
210 *((STRPTR
*) tag
->ti_Data
) = "Chris Hodges & AROS Development Team";
214 if((tag
= FindTagItem(UHA_ProductName
, taglist
))) {
215 *((STRPTR
*) tag
->ti_Data
) = "EHCI USB2.0 PCI driver";
219 if((tag
= FindTagItem(UHA_Description
, taglist
))) {
220 *((STRPTR
*) tag
->ti_Data
) = "EHCI host controller driver for PCI cards";
224 if((tag
= FindTagItem(UHA_Copyright
, taglist
))) {
225 *((STRPTR
*) tag
->ti_Data
) ="©2007-2009 Chris Hodges, ©2009-2011 AROS APL";
229 if((tag
= FindTagItem(UHA_Version
, taglist
))) {
230 *((ULONG
*) tag
->ti_Data
) = VERSION_NUMBER
;
234 if((tag
= FindTagItem(UHA_Revision
, taglist
))) {
235 *((ULONG
*) tag
->ti_Data
) = REVISION_NUMBER
;
239 if((tag
= FindTagItem(UHA_DriverVersion
, taglist
))) {
240 *((ULONG
*) tag
->ti_Data
) = 0x220;
244 if((tag
= FindTagItem(UHA_Capabilities
, taglist
))) {
245 *((ULONG
*) tag
->ti_Data
) = UHCF_USB20
;
249 ioreq
->iouh_Actual
= count
;
254 UWORD
cmdReset(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
) {
255 LIBBASETYPE
*ehd
= (LIBBASETYPE
*) LIBBASE
;
257 KPRINTF2(DBL_UHWIO
, ("EHC CMD_RESET: 0x%p\n", ioreq
));
259 // uhwDelayMS(1, unit);
260 uhwGetUsbState(ioreq
, ehu
, ehd
); /* FIXME */
262 if(ioreq
->iouh_State
& UHSF_OPERATIONAL
) {
265 return UHIOERR_USBOFFLINE
;
268 UWORD
cmdUsbReset(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
) {
269 LIBBASETYPE
*ehd
= (LIBBASETYPE
*) LIBBASE
;
271 KPRINTF2(DBL_UHWIO
, ("EHC UHCMD_USBRESET: 0x%p\n", ioreq
));
273 uhwGetUsbState(ioreq
, ehu
, ehd
); /* FIXME */
275 // ehu->ehu_FrameCounter = 1;
276 // ehu->ehu_RootHubAddr = 0;
278 if(ioreq
->iouh_State
& UHSF_OPERATIONAL
){
281 return UHIOERR_USBOFFLINE
;
284 UWORD
cmdUsbResume(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
) {
285 LIBBASETYPE
*ehd
= (LIBBASETYPE
*) LIBBASE
;
287 KPRINTF2(DBL_UHWIO
, ("EHC UHCMD_USBRESUME: 0x%p\n", ioreq
));
289 uhwGetUsbState(ioreq
, ehu
, ehd
); /* FIXME */
290 if(ioreq
->iouh_State
& UHSF_OPERATIONAL
) {
293 return UHIOERR_USBOFFLINE
;
296 UWORD
cmdUsbSuspend(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
) {
297 LIBBASETYPE
*ehd
= (LIBBASETYPE
*) LIBBASE
;
299 KPRINTF2(DBL_UHWIO
, ("EHC UHCMD_USBSUSPEND: 0x%p\n", ioreq
));
301 uhwGetUsbState(ioreq
, ehu
, ehd
); /* FIXME */
302 if(ioreq
->iouh_State
& UHSF_SUSPENDED
) {
305 return UHIOERR_USBOFFLINE
;
308 UWORD
cmdUsbOper(struct IOUsbHWReq
*ioreq
, struct ehu_unit
*ehu
, LIBBASETYPEPTR LIBBASE
) {
309 LIBBASETYPE
*ehd
= (LIBBASETYPE
*) LIBBASE
;
311 KPRINTF2(DBL_UHWIO
, ("EHC UHCMD_USBOPER: 0x%p\n", ioreq
));
313 uhwGetUsbState(ioreq
, ehu
, ehd
); /* FIXME */
314 if(ioreq
->iouh_State
& UHSF_OPERATIONAL
) {
317 return UHIOERR_USBOFFLINE
;
322 ADD2CLOSEDEV(Close
,0)