Example #1
0
int usbctrl_poll(usbctrl_softc_t * softc) {
    usbdev_t *dev = softc->dev;
    usbreq_t *ur;
    unsigned xdata_len = 0;

    uint8_t* buf = NULL;


    if (softc->is_wireless) 
    {
	uint8_t xdata[0xC] = { 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };//Request headset status command, works as a poll
        xdata_len = 0xC;
	
	buf = usb_dma_alloc(0xC);
    	if (buf == NULL) {
		printf("couldn't alloc buffer\n");
		/* Could not allocate a buffer, fail. */
		return -1;
	}
	memcpy(buf, &xdata, 0xC);
	
    }
    else 
    {
	return -1; //Polling not needed for wired controllers, and if there is a command it is not known at this time
    }

    ur = usb_make_request(dev, softc->uhid_ipipe_tx, buf, xdata_len, UR_FLAG_OUT);
    ur->ur_callback = usbctrl_set_led_callback;
    usb_queue_request(ur);

    return 0;
}
Example #2
0
int usbctrl_set_rumble(int port, uint8_t l, uint8_t r) {
    usbctrl_softc_t * softc = getcontroller(port);
    if(softc == NULL)
	return -1;
    usbdev_t *dev = softc->dev;
    usbreq_t *ur;
    unsigned xdata_len;
    uint8_t* buf = NULL;

    if(softc->is_wireless)
    {
	buf = usb_dma_alloc(0xC);

	if (buf == NULL) {
		printf("couldn't alloc buffer\n");
		/* Could not allocate a buffer, fail. */
		return -1;
	}

    	uint8_t xdata[0xC] = { 0x00, 0x01, 0x0f, 0xc0, 0x00, l, r, 0x00, 0x00, 0x00, 0x00, 0x00 };
	xdata_len = 0xC;
	memcpy(buf, &xdata, 0xC);
    }
    else
    {
	buf = usb_dma_alloc(0x8);
	 
	if (buf == NULL) {
		printf("couldn't alloc buffer\n");
		/* Could not allocate a buffer, fail. */
		return -1;
	}

	uint8_t xdata[0x8] = { 0x00, 0x08, 0x00, l, r, 0x00, 0x00, 0x00 };
	xdata_len = 0x8;
	memcpy(buf, &xdata, 0x8);
    }



    ur = usb_make_request(dev, softc->uhid_ipipe_tx, buf, xdata_len, UR_FLAG_OUT);
    ur->ur_callback = usbctrl_set_led_callback;
    usb_queue_request(ur);

    return 0;
}
Example #3
0
static void usbhub_scan_ports(usbdev_t *dev,void *arg)
{
    uint16_t current;
    uint16_t changed;
    usbhub_softc_t *softc;
    int idx;
    int res;
    int len;
    uint8_t *buf;
    usbdev_t *newdev;
    usb_driver_t *newdrv;
    int addr;
    usb_port_status_t *portstatus;
    usb_config_descr_t cfgdescr;
    unsigned int powerondelay;

    if (!IS_HUB(dev)) return;		/* should not happen.  */

    portstatus = usb_dma_alloc(sizeof(usb_port_status_t));
    if (portstatus == NULL) return;

    /*
     * We know this is a hub.  Get the softc back.
     */

    softc = (usbhub_softc_t *) dev->ud_private;

    powerondelay = ((unsigned int) softc->uhub_descr.bPowerOnToPowerGood)*2 + 20;

    /*
     * Turn on the power to the ports whose power is not yet on.
     */

    for (idx = 0; idx < softc->uhub_nports; idx++) {

	usbhub_get_port_status(dev,idx+1,portstatus);

	current = GETUSBFIELD(portstatus,wPortStatus);
	changed = GETUSBFIELD(portstatus,wPortChange);
	if (usb_noisy > 1) {
	    printf("BeforePowerup: port %d status %04X changed %04X\n",idx+1,current,changed);
	    }

	if (!(current & USB_PORT_STATUS_POWER)) {
	    if (usb_noisy > 1) console_log("USB: Powering up bus %d port %d",
				      dev->ud_bus->ub_num,idx+1);
	    usbhub_set_port_feature(dev,idx+1,USB_PORT_FEATURE_POWER);
	    usb_delay_ms(dev->ud_bus,powerondelay);
	    }
	}

    /*
     * Begin exploration at this level.
     */

    for (idx = 0; idx < softc->uhub_nports; idx++) {

	usbhub_get_port_status(dev,idx+1,portstatus);

	current = GETUSBFIELD(portstatus,wPortStatus);
	changed = GETUSBFIELD(portstatus,wPortChange);

	if (usb_noisy > 0) {
	    printf("USB: Explore: Bus %d Hub %d port %d status %04X changed %04X\n",
		   dev->ud_bus->ub_num,
		   dev->ud_address,idx+1,current,changed);
	    usb_dbg_dumpportstatus(idx+1,portstatus,1);
	    }


//	if (changed & USB_PORT_STATUS_RESET) {
//	    usbhub_clear_port_feature(dev,idx+1,USB_PORT_FEATURE_C_PORT_RESET);
//	    }

	if (changed & USB_PORT_STATUS_ENABLED) {
	    usbhub_clear_port_feature(dev,idx+1,USB_PORT_FEATURE_C_PORT_ENABLE);
	    }

	if (changed & USB_PORT_STATUS_CONNECT) {
	    /*
	     * A device was either connected or disconnected.
	     * Clear the status change first.
	     */

	    usbhub_clear_port_feature(dev,idx+1,USB_PORT_FEATURE_C_PORT_CONNECTION);

	    if (current & USB_PORT_STATUS_CONNECT) {

		/*
		 * The device has been CONNECTED.
		 */

		console_log("USB: New device connected to bus %d hub %d port %d",
			    dev->ud_bus->ub_num,
			    dev->ud_address,idx+1);

		/*
		 * Reset the device.  Reuse our old port status structure
		 * so we get the latest status.  Some devices do not report
		 * lowspeed until they are reset.
		 */

		usbhub_reset_device(dev,idx+1,portstatus);
		current = GETUSBFIELD(portstatus,wPortStatus);
		changed = GETUSBFIELD(portstatus,wPortChange);

		/*
		 * Create a device for this port.
		 */

		newdev = usb_create_device(dev->ud_bus,(current & USB_PORT_STATUS_LOWSPD) ? 1 : 0);

		/*
		 * Get the device descriptor. 
		 */

		res = usb_get_device_descriptor(newdev,&newdev->ud_devdescr,TRUE);

		if (usb_noisy > 1) usb_dbg_dumpdescriptors(newdev,(uint8_t *) &(newdev->ud_devdescr),8);

		/*
		 * Set up the max packet size for the control endpoint,
		 * then get the rest of the descriptor.
		 */
    
		usb_set_ep0mps(newdev,newdev->ud_devdescr.bMaxPacketSize0);
		res = usb_get_device_descriptor(newdev,&newdev->ud_devdescr,FALSE);

		/*
		 * Obtain a new address and set the address of the
		 * root hub to this address.
		 */

		addr = usb_new_address(newdev->ud_bus);
		res = usb_set_address(newdev,addr);

		/*
		 * Get the configuration descriptor and all the
		 * associated interface and endpoint descriptors.
		 */

		res = usb_get_config_descriptor(newdev,&cfgdescr,0,
						sizeof(usb_config_descr_t));
		if (res != sizeof(usb_config_descr_t)) {
		    printf("[a] usb_get_config_descriptor returns %d\n",res);
		    }

		len = GETUSBFIELD(&cfgdescr,wTotalLength);
		buf = usb_dma_alloc(len);

		res = usb_get_config_descriptor(newdev,(usb_config_descr_t *)buf,0,len);
		if (res != len) {
		    printf("[b] usb_get_config_descriptor returns %d\n",res);
		    }

		newdev->ud_cfgdescr = (usb_config_descr_t *) buf;

		if (usb_noisy > 1) usb_dbg_dumpdescriptors(newdev,buf,len);

		/*
		 * Point the hub at the devices it owns
		 */

		softc->uhub_devices[idx] = newdev;

		/*
		 * Find the driver for this.  It had better be the hub
		 * driver.
		 */

		newdrv = usb_find_driver(newdev);

		/*
		 * Call the attach method.
		 */

		if (newdrv) {
		    newdev->ud_drv = newdrv;	/* remember driver dispatch in device */
		    (*(newdrv->udrv_attach))(newdev,newdrv);
		    }
		}

	    else {

		/*
		 * The device has been DISCONNECTED.
		 */

		console_log("USB: Device disconnected from bus %d hub %d port %d",
			    dev->ud_bus->ub_num,
			    dev->ud_address,idx+1);

		/*
		 * Recover pointer to device below hub and clear
		 * this pointer.
		 */

		newdev = softc->uhub_devices[idx];	/* Get device pointer */

		usbhub_markdetached(newdev);		/* mark device and all subordinate 
							   devices as "removing" */

		softc->uhub_devices[idx] = NULL;	/* remove device from hub */

		/*
		 * Deassign the USB device's address and then 
		 * call detach method to free resources.  Devices that
		 * do not have drivers will not have any methods.
		 */

		if (newdev) {
		    if (newdev->ud_drv) {
			/* close open pipes, cancel reqs */
			usb_destroy_all_pipes(newdev);
			/* 
			 * Try to process the done queue.  This will complete any
			 * requests that made it out of the pipes while we were
			 * doing the stuff above.
			 */
			usb_poll(newdev->ud_bus);
			/* Call detach method, clean up device softc */
			(*(newdev->ud_drv->udrv_detach))(newdev);
			}
		    else {
			if (usb_noisy > 0) {
			    console_log("USB: Detached device on bus %d hub %d port %d "
				   "has no methods",
				   dev->ud_bus->ub_num,
				   dev->ud_address,idx+1);
			    }
			}

		    if (newdev->ud_cfgdescr) usb_dma_free(newdev->ud_cfgdescr);

		    usb_destroy_device(newdev);	
		    }

		}
	    }

	}

    usb_dma_free(portstatus);

    /*
     * Queue up a request for the interrupt pipe.  This will catch further
     * changes at this port.
     */

    usbhub_queue_intreq(dev,softc);

}
Example #4
0
static int usbhub_attach(usbdev_t *dev,usb_driver_t *drv)
{
    usb_device_status_t devstatus;
    usb_config_descr_t *cfgdscr;
    usb_interface_descr_t *ifdscr;
    usb_endpoint_descr_t *epdscr;
    usbhub_softc_t *softc;
    
    /*
     * Remember the driver dispatch.
     */

    dev->ud_drv = drv;

    softc = KMALLOC(sizeof(usbhub_softc_t),0);
    memset(softc,0,sizeof(usbhub_softc_t));
    softc->uhub_imsg = NULL;
    dev->ud_private = softc;

    /*
     * Dig out the data from the configuration descriptor
     * (we got this from the device before attach time)
     */

    cfgdscr = dev->ud_cfgdescr;
    epdscr = usb_find_cfg_descr(dev,USB_ENDPOINT_DESCRIPTOR_TYPE,0);
    ifdscr = usb_find_cfg_descr(dev,USB_INTERFACE_DESCRIPTOR_TYPE,0);

    /*
     * Get device status (is this really necessary?)
     */

    usb_get_device_status(dev,&devstatus);

    /*
     * Set us to configuration index 0
     */

    usb_set_configuration(dev,cfgdscr->bConfigurationValue);

    /*
     * Get the hub descriptor.
     */

    usbhub_get_hub_descriptor(dev,&softc->uhub_descr,0,sizeof(usb_hub_descr_t));

    /*	
     * remember stuff from the hub descriptor
     */

    softc->uhub_nports = softc->uhub_descr.bNumberOfPorts;

    /*
     * Open the interrupt pipe
     */

    softc->uhub_ipipemps = GETUSBFIELD(epdscr,wMaxPacketSize);
    softc->uhub_imsg = usb_dma_alloc(softc->uhub_ipipemps);
    softc->uhub_ipipe = usb_open_pipe(dev,epdscr);

    /*
     * Mark the bus and the hub as needing service.
     */

    softc->uhub_flags |= UHUB_FLG_NEEDSCAN;
    dev->ud_bus->ub_flags |= UB_FLG_NEEDSCAN;

    /*
     * Okay, that's it.  The top-level USB daemon will notice
     * that the bus needs service and will invoke the exploration code.
     * This may in turn require additional explores until
     * everything settles down.
     */

    return 0;
}
Example #5
0
static int usbctrl_attach(usbdev_t *dev,usb_driver_t *drv)
{
	usb_config_descr_t *cfgdscr = dev->ud_cfgdescr;
	//printf("Number of interfaces: %i\n", cfgdscr->bNumInterfaces);



	dev->ud_drv = drv;

	usbctrl_softc_t *softc;

	



	//printf("Number of endpoints: %i\n", ifdscr->bNumEndpoints);

	usb_endpoint_descr_t *epdscr;
	usb_interface_descr_t *ifdscr;

	int wireless = (GETUSBFIELD(&dev->ud_devdescr, idProduct) == 0x291) || 
			(GETUSBFIELD(&dev->ud_devdescr, idProduct) == 0x2aa) ||
			(GETUSBFIELD(&dev->ud_devdescr, idProduct) == 0x2a9);

	if(wireless)
	{

		dev->ud_private = NULL;


		int i;
		for(i = 0; i < 4; i++)
		{
			softc = KMALLOC(sizeof(usbctrl_softc_t),0);
			softc->dev = dev;
			softc->is_wireless = (wireless);
			epdscr = usb_find_cfg_descr(dev,USB_ENDPOINT_DESCRIPTOR_TYPE,i * 4);
			ifdscr = usb_find_cfg_descr(dev,USB_INTERFACE_DESCRIPTOR_TYPE,i * 2);

			if (!epdscr || !ifdscr) {
				printf("couldn't find descriptor for controller %i!\n", i);
				return 0;
			}
		

			//printf("Initializing wireless controller %d\n", i);
			softc->index = -1;
			softc->wireless_index = i;
			//controller_mask |= 1<<i; //Dont set this right now, let wired controllers use the slots

			/*
			 * Allocate a DMA buffer
			 */

			softc->uhid_imsg = usb_dma_alloc(UBR_KBD_MAX);
			if (softc->uhid_imsg == NULL) {
				printf("couldn't alloc buffer\n");
				/* Could not allocate a buffer, fail. */
				return -1;
			}
	
			/*
			 * Choose the standard configuration.
	 		*/

			usb_set_configuration(dev,cfgdscr->bConfigurationValue);

			/*
	 		* Open the interrupt pipe.
	 		*/

			softc->uhid_ipipe = usb_open_pipe(dev,epdscr);
			
			usb_endpoint_descr_t *txdscr = usb_find_cfg_descr(dev, USB_ENDPOINT_DESCRIPTOR_TYPE, (i * 4) + 1);
			//if (USB_ENDPOINT_DIR_OUT(txdscr->bEndpointAddress))
			//	printf("Opened an outgoing endpoint\n");

			softc->uhid_ipipe_tx = usb_open_pipe(dev, txdscr);

			

			softc->uhid_ipipemps = GETUSBFIELD(epdscr,wMaxPacketSize);
			softc->uhid_ipipemps_tx = GETUSBFIELD(epdscr,wMaxPacketSize);

			usbctrl_set_leds(softc, 1); //Clear leds, FIXME: Implement controller shutdown somewhere
			usbctrl_poll(softc);

			/*
			 * Queue a transfer on the interrupt endpoint to catch
			 * our first characters.
	 		*/

			usbctrl_queue_intreq(dev,softc);

			

		}


	}
	else
	{

	softc = KMALLOC(sizeof(usbctrl_softc_t),0);
	memset(softc,0,sizeof(usbctrl_softc_t));
	softc->dev = dev;
	dev->ud_private = softc;

	softc->is_wireless = (wireless);

	epdscr = usb_find_cfg_descr(dev,USB_ENDPOINT_DESCRIPTOR_TYPE,0);
	ifdscr = usb_find_cfg_descr(dev,USB_INTERFACE_DESCRIPTOR_TYPE,0);

	usb_endpoint_descr_t *txdscr = usb_find_cfg_descr(dev, USB_ENDPOINT_DESCRIPTOR_TYPE,1);

	
	//if (USB_ENDPOINT_DIR_OUT(txdscr->bEndpointAddress))
	//	printf("Opened an outgoing endpoint\n");

	softc->uhid_ipipe_tx = usb_open_pipe(dev, txdscr);

	if (!epdscr || !ifdscr) {
		printf("couldn't find descriptor!\n");
		return 0;
	}
	

	
	int i;
	for (i = 0; controller_mask & (1<<i); ++i);
	printf("attached controller %d\n", i);
	softc->index = i;
	setcontroller(softc, i);
	controller_mask |= 1<<i;

	/*
	 * Allocate a DMA buffer
	 */

	softc->uhid_imsg = usb_dma_alloc(UBR_KBD_MAX);
	if (softc->uhid_imsg == NULL) {
		printf("couldn't alloc buffer\n");
		/* Could not allocate a buffer, fail. */
		return -1;
	}
	
	/*
	 * Choose the standard configuration.
	 */

	usb_set_configuration(dev,cfgdscr->bConfigurationValue);

	/*
	 * Open the interrupt pipe.
	 */

	softc->uhid_ipipe = usb_open_pipe(dev,epdscr);
	softc->uhid_ipipemps = GETUSBFIELD(epdscr,wMaxPacketSize);

	/*
	 * Queue a transfer on the interrupt endpoint to catch
	 * our first characters.
	 */
	usbctrl_set_leds(softc, 0);
	usbctrl_queue_intreq(dev,softc);


	}

	return 0;


}
Example #6
0
static int usbhid_attach(usbdev_t *dev,usb_driver_t *drv)
{
    usb_config_descr_t *cfgdscr = dev->ud_cfgdescr;
    usb_endpoint_descr_t *epdscr;
    usb_interface_descr_t *ifdscr;
    usbhid_softc_t *softc;

    dev->ud_drv = drv;

    softc = KMALLOC(sizeof(usbhid_softc_t),0);
    memset(softc,0,sizeof(usbhid_softc_t));
    dev->ud_private = softc;

    epdscr = usb_find_cfg_descr(dev,USB_ENDPOINT_DESCRIPTOR_TYPE,0);
    ifdscr = usb_find_cfg_descr(dev,USB_INTERFACE_DESCRIPTOR_TYPE,0);

    if (!epdscr || !ifdscr) {
	/*
	 * Could not get descriptors, something is very wrong.
	 * Leave device addressed but not configured.
	 */
	return 0;
	}

    /*
     * Allocate a DMA buffer
     */

    softc->uhid_imsg = usb_dma_alloc(UBR_KBD_MAX);
    if (softc->uhid_imsg == NULL) {
	/* Could not allocate a buffer, fail. */
	return -1;
	}

    /*
     * Choose the standard configuration.
     */

    usb_set_configuration(dev,cfgdscr->bConfigurationValue);

    /*
     * Set the protocol to the "boot" protocol, so we don't
     * have to deal with fancy HID stuff.
     */

    usbhid_set_protocol(dev,HID_BOOT_PROTOCOL,ifdscr->bInterfaceNumber);

    /*
     * Open the interrupt pipe.
     */

    softc->uhid_ipipe = usb_open_pipe(dev,epdscr);
    softc->uhid_ipipemps = GETUSBFIELD(epdscr,wMaxPacketSize);

    /*
     * Figure out the device type from the protocol.  Keyboards,
     * mice use this field to distinguish themselves.
     */

    softc->uhid_devtype = ifdscr->bInterfaceProtocol;
    if (softc->uhid_devtype > HID_DEVTYPE_MAX) {
	softc->uhid_devtype = HID_DEVTYPE_UNKNOWN;
	}

    console_log("USBHID: %s Configured.\n",
	   usbhid_devtypes[softc->uhid_devtype]);

    /*
     * Queue a transfer on the interrupt endpoint to catch
     * our first characters.
     */

    usbhid_queue_intreq(dev,softc);

    return 0;
}