uint32_t urndis_ctrl_query(struct NepClassEth *ncp, uint32_t oid, void *qbuf, size_t qlen, void **rbuf, size_t *rbufsz) { struct urndis_query_req *msg; uint32_t rval; struct urndis_comp_hdr *hdr; msg = psdAllocVec(sizeof(*msg) + qlen); if (msg == NULL) { bug("%s: out of memory\n", DEVNAME); return RNDIS_STATUS_FAILURE; } msg->rm_type = htole32(REMOTE_NDIS_QUERY_MSG); msg->rm_len = htole32(sizeof(*msg) + qlen); msg->rm_rid = 0; /* XXX */ msg->rm_oid = htole32(oid); msg->rm_infobuflen = htole32(qlen); if (qlen != 0) { msg->rm_infobufoffset = htole32(20); memcpy((char*)msg + 20, qbuf, qlen); } else msg->rm_infobufoffset = 0; msg->rm_devicevchdl = 0; bug("%s: urndis_ctrl_query send: type %u len %u rid %u oid 0x%x " "infobuflen %u infobufoffset %u devicevchdl %u\n", DEVNAME, letoh32(msg->rm_type), letoh32(msg->rm_len), letoh32(msg->rm_rid), letoh32(msg->rm_oid), letoh32(msg->rm_infobuflen), letoh32(msg->rm_infobufoffset), letoh32(msg->rm_devicevchdl)); rval = urndis_ctrl_send(ncp, msg, sizeof(*msg)); psdFreeVec(msg); if (rval != RNDIS_STATUS_SUCCESS) { bug("%s: query failed\n", DEVNAME); return rval; } if ((hdr = urndis_ctrl_recv(ncp)) == NULL) { bug("%s: unable to get query response\n", DEVNAME); return RNDIS_STATUS_FAILURE; } rval = urndis_ctrl_handle(ncp, hdr, rbuf, rbufsz); return rval; }
/* /// "usbForceInterfaceBinding()" */ struct NepClassHid * usbForceInterfaceBinding(struct NepHidBase *nh, struct PsdInterface *pif) { struct Library *ps; struct NepClassHid *nch; struct PsdConfig *pc; struct PsdDevice *pd; STRPTR devname; UBYTE buf[64]; struct Task *tmptask; KPRINTF(1, ("nepHidAttemptInterfaceBinding(%08lx)\n", pif)); if((ps = OpenLibrary("poseidon.library", 4))) { if((nch = psdAllocVec(sizeof(struct NepClassHid)))) { nch->nch_ClsBase = nh; nch->nch_Device = NULL; nch->nch_Interface = pif; nLoadClassConfig(nh); psdSafeRawDoFmt(buf, 64, "simplemidi.class<%08lx>", nch); nch->nch_ReadySignal = SIGB_SINGLE; nch->nch_ReadySigTask = FindTask(NULL); SetSignal(0, SIGF_SINGLE); if((tmptask = psdSpawnSubTask(buf, nHidTask, nch))) { psdBorrowLocksWait(tmptask, 1UL<<nch->nch_ReadySignal); if(nch->nch_Task) { nch->nch_ReadySigTask = NULL; //FreeSignal(nch->nch_ReadySignal); psdGetAttrs(PGA_INTERFACE, pif, IFA_Config, &pc, TAG_END); psdGetAttrs(PGA_CONFIG, pc, CA_Device, &pd, TAG_END); psdGetAttrs(PGA_DEVICE, pd, DA_ProductName, &devname, TAG_END); psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "Play it again, '%s'!", devname); CloseLibrary(ps); return(nch); } } nch->nch_ReadySigTask = NULL; //FreeSignal(nch->nch_ReadySignal); psdFreeVec(nch); } CloseLibrary(ps); } return(NULL); }
uint32_t urndis_ctrl_init(struct NepClassEth *ncp) { struct urndis_init_req *msg; uint32_t rval; struct urndis_comp_hdr *hdr; msg = psdAllocVec(sizeof(*msg)); if (msg == NULL) { bug("out of memory\n"); return RNDIS_STATUS_FAILURE; } msg->rm_type = htole32(REMOTE_NDIS_INITIALIZE_MSG); msg->rm_len = htole32(sizeof(*msg)); msg->rm_rid = htole32(0); msg->rm_ver_major = htole32(1); msg->rm_ver_minor = htole32(1); msg->rm_max_xfersz = htole32(RNDIS_BUFSZ); bug("%s: urndis_ctrl_init send: type %u len %u rid %u ver_major %u " "ver_minor %u max_xfersz %u\n", DEVNAME, letoh32(msg->rm_type), letoh32(msg->rm_len), letoh32(msg->rm_rid), letoh32(msg->rm_ver_major), letoh32(msg->rm_ver_minor), letoh32(msg->rm_max_xfersz)); //Delay(50); rval = urndis_ctrl_send(ncp, msg, sizeof(*msg)); psdFreeVec(msg); if (rval != 0 ) { bug("%s: init failed\n", DEVNAME); return rval; } if ((hdr = urndis_ctrl_recv(ncp)) == NULL) { bug("%s: unable to get init response\n", DEVNAME); return RNDIS_STATUS_FAILURE; } rval = urndis_ctrl_handle(ncp, hdr, NULL, NULL); return rval; }
/* /// "nAllocGHCItem()" */ struct NepHidGItem * nAllocGHCItem(struct NepClassHid *nch, struct NepHidItem *nhi, struct List *actionlist, ULONG usageid) { struct NepHidGItem *nhgi; if(!(nhgi = psdAllocVec(sizeof(struct NepHidGItem)))) { return(NULL); } nhgi->nhgi_Item = nhi; nhgi->nhgi_ActionList = actionlist; if(usageid) { nhgi->nhgi_Name = nGetGHCUsageName(nch, usageid); } AddTail(&nch->nch_HCGUIItems, &nhgi->nhgi_Node); return(nhgi); }
struct urndis_comp_hdr * urndis_ctrl_recv(struct NepClassEth *ncp) { struct urndis_comp_hdr *hdr; char *buf; LONG err; LONG sc_ifaceno_ctl=0; buf = psdAllocVec(RNDIS_RESPONSE_LEN); if (buf == NULL) { bug("%s: out of memory\n", DEVNAME); return NULL; } err = urndis_ctrl_msg(ncp, UT_READ_CLASS_INTERFACE, UR_CLEAR_FEATURE, sc_ifaceno_ctl, 0, buf, RNDIS_RESPONSE_LEN); if (err != 0) { bug("%s: urndis_comp_hdr error\n", DEVNAME); psdFreeVec(buf); return NULL; } hdr = (struct urndis_comp_hdr *)buf; bug("%s: urndis_ctrl_recv: type 0x%x len %u\n", DEVNAME, hdr->rm_type, letoh32(hdr->rm_len)); //dumpmem(buf,hdr->rm_len); if (letoh32(hdr->rm_len) > RNDIS_RESPONSE_LEN) { bug("%s: ctrl message error: wrong size %u > %u\n", DEVNAME, letoh32(hdr->rm_len), RNDIS_RESPONSE_LEN); psdFreeVec(buf); return NULL; } return hdr; }
struct FELSunxiDevice * ForceDeviceBinding(LIBBASETYPEPTR LIBBASE, struct PsdDevice *pd) { mybug(-1,("FELSunxi ForceDeviceBinding\n")); struct FELSunxiDevice *FELSunxiDevice; struct Library *ps; if((ps = OpenLibrary("poseidon.library", 4))) { FELSunxiDevice = psdAllocVec(sizeof(struct FELSunxiDevice)); if(FELSunxiDevice) { FELSunxiDevice->ps = ps; FELSunxiDevice->pd = pd; /* Open MUI for FELSunxiTask, don't bother to continue if it fails */ FELSunxiDevice->MUIMasterBase = OpenLibrary("muimaster.library", 0); if(FELSunxiDevice->MUIMasterBase) { mybug(-1,("Creating FELSunxiTask\n")); FELSunxiDevice->readysignal = SIGB_SINGLE; FELSunxiDevice->readysigtask = FindTask(NULL); SetSignal(0, SIGF_SINGLE); FELSunxiDevice->felsunxitask = psdSpawnSubTask("FELSunxi task", FELSunxiTask, FELSunxiDevice); if(FELSunxiDevice->felsunxitask) { /* Wait for FELSunxiTask to be ready */ psdBorrowLocksWait(FELSunxiDevice->felsunxitask, 1UL<<FELSunxiDevice->readysignal); return FELSunxiDevice; } else { mybug(-1,("Failed to spawn the task\n")); } CloseLibrary(FELSunxiDevice->MUIMasterBase); } psdFreeVec(FELSunxiDevice); } CloseLibrary(ps); } return NULL; }
/* /// "usbForceInterfaceBinding()" */ struct NepClassHid * usbForceInterfaceBinding(struct NepHidBase *nh, struct PsdInterface *pif) { struct Library *ps; struct NepClassHid *nch; struct PsdConfig *pc; struct PsdDevice *pd; STRPTR devname; STRPTR ifidstr; STRPTR devidstr; UBYTE buf[64]; struct Task *tmptask; KPRINTF(1, ("nepHidForceInterfaceBinding(%08lx)\n", pif)); if((ps = OpenLibrary("poseidon.library", 4))) { psdGetAttrs(PGA_INTERFACE, pif, IFA_Config, &pc, IFA_IDString, &ifidstr, TAG_DONE); psdGetAttrs(PGA_CONFIG, pc, CA_Device, &pd, TAG_END); psdGetAttrs(PGA_DEVICE, pd, DA_ProductName, &devname, DA_IDString, &devidstr, TAG_END); if((nch = psdAllocVec(sizeof(struct NepClassHid)))) { nch->nch_ClsBase = nh; nch->nch_CDC = psdAllocVec(sizeof(struct ClsDevCfg)); if(!nch->nch_CDC) { psdFreeVec(nch); CloseLibrary(ps); return(NULL); } nch->nch_Device = pd; nch->nch_Interface = pif; nch->nch_DevIDString = devidstr; nch->nch_IfIDString = ifidstr; nLoadBindingConfig(nch); psdSafeRawDoFmt(buf, 64, "bootmouse.class<%08lx>", nch); nch->nch_ReadySignal = SIGB_SINGLE; nch->nch_ReadySigTask = FindTask(NULL); SetSignal(0, SIGF_SINGLE); if((tmptask = psdSpawnSubTask(buf, nHidTask, nch))) { psdBorrowLocksWait(tmptask, 1UL<<nch->nch_ReadySignal); if(nch->nch_Task) { nch->nch_ReadySigTask = NULL; //FreeSignal(nch->nch_ReadySignal); psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "I'm pleased to introduce a mouse alliance to '%s'!", devname); Forbid(); AddTail(&nh->nh_Bindings, &nch->nch_Node); Permit(); CloseLibrary(ps); return(nch); } } nch->nch_ReadySigTask = NULL; //FreeSignal(nch->nch_ReadySignal); psdFreeVec(nch->nch_CDC); psdFreeVec(nch); } CloseLibrary(ps); } return(NULL); }
/* /// "usbForceInterfaceBinding()" */ struct NepClassHid * usbForceInterfaceBinding(struct NepHidBase *nh, struct PsdInterface *pif) { struct Library *ps; struct Library *DOSBase; struct NepClassHid *nch; struct PsdConfig *pc; struct PsdDevice *pd; STRPTR devname; UBYTE buf[64]; struct Task *tmptask; KPRINTF(1, ("nepHidAttemptInterfaceBinding(%08lx)\n", pif)); if((ps = OpenLibrary("poseidon.library", 4))) { if((nch = psdAllocVec(sizeof(struct NepClassHid)))) { STRPTR srcpos; STRPTR tarpos; UWORD cnt; psdGetAttrs(PGA_INTERFACE, pif, IFA_Config, &pc, TAG_END); psdGetAttrs(PGA_CONFIG, pc, CA_Device, &pd, TAG_END); psdGetAttrs(PGA_DEVICE, pd, DA_ProductName, &devname, TAG_END); // generate ID srcpos = devname; tarpos = nch->nch_ShortID; cnt = 31; while(*srcpos && cnt) { if(((*srcpos >= 'A') && (*srcpos <= 'Z')) || ((*srcpos >= 'a') && (*srcpos <= 'z')) || ((*srcpos >= '0') && (*srcpos <= '9'))) { *tarpos++ = *srcpos; cnt--; } srcpos++; } *tarpos = 0; nch->nch_ClsBase = nh; nch->nch_Device = NULL; nch->nch_Interface = pif; nLoadClassConfig(nh); psdSafeRawDoFmt(buf, 64, "camdusbmidi.class<%08lx>", nch); nch->nch_ReadySignal = SIGB_SINGLE; nch->nch_ReadySigTask = FindTask(NULL); SetSignal(0, SIGF_SINGLE); if((tmptask = psdSpawnSubTask(buf, nHidTask, nch))) { psdBorrowLocksWait(tmptask, 1UL<<nch->nch_ReadySignal); if(nch->nch_Task) { nch->nch_ReadySigTask = NULL; //FreeSignal(nch->nch_ReadySignal); Forbid(); AddTail(&nh->nh_Bindings, &nch->nch_Node); Permit(); psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "Play it again, '%s'!", devname); if((DOSBase = OpenLibrary("dos.library", 37))) { BPTR fh; BPTR lock; psdSafeRawDoFmt(buf, 64, "%s/%s", (STRPTR) "DEVS:Midi", nch->nch_ShortID); fh = Open(buf, MODE_OLDFILE); if(!fh) { fh = Open(buf, MODE_NEWFILE); if(!fh) { lock = CreateDir("DEVS:Midi"); if(lock) { UnLock(lock); psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "Created directory '%s'!", (STRPTR) "DEVS:Midi"); } fh = Open(buf, MODE_NEWFILE); } if(!fh) { psdAddErrorMsg(RETURN_ERROR, (STRPTR) libname, "Couldn't generate CAMD MIDI driver '%s'!", buf); } else { UBYTE *tmpmem = psdAllocVec(sizeof(CAMDDriver)); if(tmpmem) { CopyMemQuick(CAMDDriver, tmpmem, sizeof(CAMDDriver)); // fix name of driver -- position is hardcoded, but unlikely to move strcpy(&tmpmem[0x46], nch->nch_ShortID); Write(fh, tmpmem, sizeof(CAMDDriver)); psdFreeVec(tmpmem); psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "Generated CAMD MIDI driver '%s'!", buf); } Close(fh); } } else { Close(fh); } CloseLibrary(DOSBase); } CloseLibrary(ps); return(nch); } } nch->nch_ReadySigTask = NULL; //FreeSignal(nch->nch_ReadySignal); psdFreeVec(nch); } CloseLibrary(ps); } return(NULL); }
uint32_t urndis_ctrl_handle_query(struct NepClassEth *ncp, const struct urndis_comp_hdr *hdr, void **buf, size_t *bufsz) { const struct urndis_query_comp *msg; msg = (struct urndis_query_comp *) hdr; bug("%s: urndis_ctrl_handle_query: len %u rid %u status 0x%x " "buflen %u bufoff %u\n", DEVNAME, letoh32(msg->rm_len), letoh32(msg->rm_rid), letoh32(msg->rm_status), letoh32(msg->rm_infobuflen), letoh32(msg->rm_infobufoffset)); if (buf && bufsz) { *buf = NULL; *bufsz = 0; } if (letoh32(msg->rm_status) != RNDIS_STATUS_SUCCESS) { bug("%s: query failed 0x%x\n", DEVNAME, letoh32(msg->rm_status)); return letoh32(msg->rm_status); } if (letoh32(msg->rm_infobuflen) + letoh32(msg->rm_infobufoffset) + RNDIS_HEADER_OFFSET > letoh32(msg->rm_len)) { bug("%s: ctrl message error: invalid query info " "len/offset/end_position(%d/%d/%d) -> " "go out of buffer limit %d\n", DEVNAME, letoh32(msg->rm_infobuflen), letoh32(msg->rm_infobufoffset), letoh32(msg->rm_infobuflen) + letoh32(msg->rm_infobufoffset) + RNDIS_HEADER_OFFSET, letoh32(msg->rm_len)); return RNDIS_STATUS_FAILURE; } if (buf && bufsz) { *buf = psdAllocVec(letoh32(msg->rm_infobuflen)); if (*buf == NULL) { bug("%s: out of memory\n", DEVNAME); return RNDIS_STATUS_FAILURE; } else { char *p; *bufsz = letoh32(msg->rm_infobuflen); p = (char *)&msg->rm_rid; p += letoh32(msg->rm_infobufoffset); memcpy(*buf, p, letoh32(msg->rm_infobuflen)); } } return letoh32(msg->rm_status); }