#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include "usb.h"
#include "kernel.h"


USB_StringDescriptor* USB_makeStringDescriptor(USBDevice* device,int i)
{
    if (i<1 || i>=0x100) return 0;

    USB_StringDescriptor lang;
    _kernel_oserror* e;
    e = USB_control(device,0x80,6,0x300,0,sizeof(USB_StringDescriptor),&lang);
    if (e) return 0;
    USB_Descriptor size;
    e = USB_control(device,0x80,6,0x300+i,lang.str[0],sizeof(USB_Descriptor),&size);
    if (e) return 0;
    USB_StringDescriptor *str=calloc(size.bLength,1);
    if (str) e = USB_control(device,0x80,6,0x300+i,lang.str[0],size.bLength,str);
    return str;
}

_kernel_oserror* USB_setNoPad(USBDevice* device,int fsHandle,int on)
{
    int usbHandle;
    _kernel_oserror* e=_swix(DeviceFS_CallDevice,_INR(0,2) | _OUT(5),(1u<<31)+7,device,fsHandle,&usbHandle);
    if (!e) e=_swix(DeviceFS_CallDevice,_INR(0,4),(1u<<31)+8,device,usbHandle,(on?1:0),~1);
    return e;
}

_kernel_oserror* USB_setShort(USBDevice* device,int fsHandle,int on)
{
    int usbHandle;
    _kernel_oserror* e=_swix(DeviceFS_CallDevice,_INR(0,2) | _OUT(5),(1u<<31)+7,device,fsHandle,&usbHandle);
    if (!e) e=_swix(DeviceFS_CallDevice,_INR(0,4),(1u<<31)+8,device,usbHandle,(on?2:0),~2);
    return e;
}

_kernel_oserror* USB_getDeviceHandle(const char* name, USBDevice** handle)
{
    return _swix(DeviceFS_CallDevice,_INR(0,1) | _OUT(3),(1u<<31)+9,name,handle);
}

USB_ConnectedDeviceList* USB_makeConnectedDeviceList(void)
{
    USB_ConnectedDeviceList* list;
    return (_swix(OS_ServiceCall,_INR(0,2) | _OUT(2),1,0xD2,0,&list))?0:list;
}

void USB_destroyConnectedDeviceList(USB_ConnectedDeviceList* list)
{
    USB_ConnectedDeviceList* next;
    for (;list;list=next)
    {
        next = list->next;
        free(list);
    }
}

USB_Descriptor* USB_getDescriptorList(USB_ServiceCall* item)
{
    return (USB_Descriptor*)(((int)item)+item->descOffset);
}
