+ pAlternateSettings[j] = &(iface->pAlternateSettings);
+ iface->dwNumAltSettings = usbdevice->config[i].interface[j].num_altsetting;
+ pActiveAltSetting[j] = &(iface->pActiveAltSetting);
+
+ len += sizeof(WDU_INTERFACE);
+ }
+ } else {
+ len += sizeof(WDU_INTERFACE) * conf_desc->bNumInterfaces;
+ }
+
+ for (j=0; j<conf_desc->bNumInterfaces; j++)
+ {
+ struct usb_interface *interface = &usbdevice->config[i].interface[j];
+
+ if (buf) {
+ *pAlternateSettings[j] = (WDU_ALTERNATE_SETTING*)(buf+len);
+ /* FIXME: */
+ *pActiveAltSetting[j] = (WDU_ALTERNATE_SETTING*)(buf+len);
+ }
+
+ for(k=0; k<interface->num_altsetting; k++)
+ {
+ unsigned char bNumEndpoints = interface->altsetting[k].bNumEndpoints;
+ WDU_ENDPOINT_DESCRIPTOR **pEndpointDescriptors;
+ WDU_PIPE_INFO **pPipes;
+
+ if (buf) {
+ WDU_ALTERNATE_SETTING *altset = (WDU_ALTERNATE_SETTING*)(buf+len);
+
+ altset->Descriptor.bLength = interface->altsetting[k].bLength;
+ altset->Descriptor.bDescriptorType = interface->altsetting[k].bDescriptorType;
+ altset->Descriptor.bInterfaceNumber = interface->altsetting[k].bInterfaceNumber;
+ altset->Descriptor.bAlternateSetting = interface->altsetting[k].bAlternateSetting;
+ altset->Descriptor.bNumEndpoints = interface->altsetting[k].bNumEndpoints;
+ altset->Descriptor.bInterfaceClass = interface->altsetting[k].bInterfaceClass;
+ altset->Descriptor.bInterfaceSubClass = interface->altsetting[k].bInterfaceSubClass;
+ altset->Descriptor.bInterfaceProtocol = interface->altsetting[k].bInterfaceProtocol;
+ altset->Descriptor.iInterface = interface->altsetting[k].iInterface;
+ pEndpointDescriptors = &(altset->pEndpointDescriptors);
+ pPipes = &(altset->pPipes);
+
+ }
+ len +=sizeof(WDU_ALTERNATE_SETTING);
+
+ if (buf) {
+ *pEndpointDescriptors = (WDU_ENDPOINT_DESCRIPTOR*)(buf+len);
+ for (l = 0; l < bNumEndpoints; l++) {
+ WDU_ENDPOINT_DESCRIPTOR *ed = (WDU_ENDPOINT_DESCRIPTOR*)(buf+len);
+
+ ed->bLength = interface->altsetting[k].endpoint[l].bLength;
+ ed->bDescriptorType = interface->altsetting[k].endpoint[l].bDescriptorType;
+ ed->bEndpointAddress = interface->altsetting[k].endpoint[l].bEndpointAddress;
+ ed->bmAttributes = interface->altsetting[k].endpoint[l].bmAttributes;
+ ed->wMaxPacketSize = interface->altsetting[k].endpoint[l].wMaxPacketSize;
+ ed->bInterval = interface->altsetting[k].endpoint[l].bInterval;
+
+ len += sizeof(WDU_ENDPOINT_DESCRIPTOR);
+ }
+
+ *pPipes = (WDU_PIPE_INFO*)(buf+len);
+ for (l = 0; l < bNumEndpoints; l++) {
+ WDU_PIPE_INFO *pi = (WDU_PIPE_INFO*)(buf+len);
+
+ pi->dwNumber = interface->altsetting[k].endpoint[l].bEndpointAddress;
+ pi->dwMaximumPacketSize = WDU_GET_MAX_PACKET_SIZE(interface->altsetting[k].endpoint[l].wMaxPacketSize);
+ pi->type = interface->altsetting[k].endpoint[l].bmAttributes & USB_ENDPOINT_TYPE_MASK;
+ if (pi->type == PIPE_TYPE_CONTROL)
+ pi->direction = WDU_DIR_IN_OUT;
+ else
+ {
+ pi->direction = interface->altsetting[k].endpoint[l].bEndpointAddress & USB_ENDPOINT_DIR_MASK ? WDU_DIR_IN : WDU_DIR_OUT;
+ }
+
+ pi->dwInterval = interface->altsetting[k].endpoint[l].bInterval;
+
+ len += sizeof(WDU_PIPE_INFO);
+ }
+ } else {
+ len +=(sizeof(WDU_ENDPOINT_DESCRIPTOR)+sizeof(WDU_PIPE_INFO))*bNumEndpoints;
+ }
+ }
+ }
+ }
+
+ return len;
+}
+
+int pp_transfer(WD_TRANSFER *tr, int fd, unsigned int request, unsigned char *wdioctl) {
+ int ret = 0;
+ unsigned long port = (unsigned long)tr->dwPort;
+ unsigned char val;
+ static int last_pp_write = 0;
+
+ DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
+ (unsigned long)tr->dwPort, tr->cmdTrans, tr->dwBytes,
+ tr->fAutoinc, tr->dwOptions);
+
+ val = tr->Data.Byte;
+
+#ifdef DEBUG
+ if (tr->cmdTrans == 13)
+ DPRINTF("write byte: %d\n", val);
+#endif
+
+#ifndef NO_WINDRVR
+ ret = (*ioctl_func) (fd, request, wdioctl);
+#else
+ if (parportfd < 0)
+ return ret;
+
+ if (port == ppbase + PP_DATA) {
+ DPRINTF("data port\n");
+ switch(tr->cmdTrans) {
+ case PP_READ:
+ ret = 0; /* We don't support reading of the data port */
+ break;
+
+ case PP_WRITE:
+ ret = ioctl(parportfd, PPWDATA, &val);
+ last_pp_write = val;
+ break;
+
+ default:
+ fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr->cmdTrans);
+ ret = -1;
+ break;
+ }
+ } else if (port == ppbase + PP_STATUS) {
+ DPRINTF("status port (last write: %d)\n", last_pp_write);
+ switch(tr->cmdTrans) {
+ case PP_READ:
+ ret = ioctl(parportfd, PPRSTATUS, &val);
+#ifdef FORCE_PC3_IDENT
+ val &= 95;
+ if (last_pp_write & 64)
+ val |= 32;
+ else
+ val |= 128;
+#endif
+ break;
+
+ case PP_WRITE:
+ ret = 0; /* Status Port is readonly */
+ break;
+
+ default:
+ fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr->cmdTrans);
+ ret = -1;
+ break;
+ }
+ } else if (port == ppbase + PP_CONTROL) {
+ DPRINTF("control port\n");
+ switch(tr->cmdTrans) {
+ case PP_READ:
+ ret = ioctl(parportfd, PPRCONTROL, &val);
+ break;
+
+ case PP_WRITE:
+ ret = ioctl(parportfd, PPWCONTROL, &val);
+ break;
+
+ default:
+ fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr->cmdTrans);
+ ret = -1;
+ break;
+ }
+ } else if ((port == ecpbase + PP_ECP_CFGA) && ecpbase) {
+ DPRINTF("ECP_CFGA port\n");
+ } else if ((port == ecpbase + PP_ECP_CFGB) && ecpbase) {
+ DPRINTF("ECP_CFGB port\n");
+ } else if ((port == ecpbase + PP_ECP_ECR) && ecpbase) {
+ DPRINTF("ECP_ECR port\n");
+ } else {
+ DPRINTF("access to unsupported address range!\n");
+ ret = 0;
+ }
+
+ tr->Data.Byte = val;
+#endif
+
+ DPRINTF("dwPortReturn: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
+ (unsigned long)tr->dwPort, tr->cmdTrans, tr->dwBytes,
+ tr->fAutoinc, tr->dwOptions);
+#ifdef DEBUG
+ if (tr->cmdTrans == 10)
+ DPRINTF("read byte: %d\n", tr->Data.Byte);
+#endif
+
+ return ret;
+}