Esempio n. 1
0
static int
run_schedule (usbdev_t *dev, td_t *td)
{
	UHCI_INST (dev->controller)->qh_data->elementlinkptr =
		virt_to_phys (td) & ~(FLISTP_QH | FLISTP_TERMINATE);
	td = wait_for_completed_qh (dev->controller,
				    UHCI_INST (dev->controller)->qh_data);
	if (td == 0) {
		return 0;
	} else {
		td_dump (td);
		return 1;
	}
}
Esempio n. 2
0
static int
run_schedule (usbdev_t *dev, td_t *td)
{
	UHCI_INST (dev->controller)->qh_data->elementlinkptr.ptr =
		virt_to_phys (td);
	UHCI_INST (dev->controller)->qh_data->elementlinkptr.queue_head = 0;
	UHCI_INST (dev->controller)->qh_data->elementlinkptr.terminate = 0;
	td = wait_for_completed_qh (dev->controller,
				    UHCI_INST (dev->controller)->qh_data);
	if (td == 0) {
		return 0;
	} else {
		td_dump (td);
		return 1;
	}
}
Esempio n. 3
0
static int
uhci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen,
	      unsigned char *data)
{
	int endp = 0;		/* this is control: always 0 */
	int mlen = dev->endpoints[0].maxpacketsize;
	int count = (2 + (dalen + mlen - 1) / mlen);
	unsigned short req = ((unsigned short *) devreq)[0];
	int i;
	td_t *tds = memalign (16, sizeof (td_t) * count);
	memset (tds, 0, sizeof (td_t) * count);
	count--;		/* to compensate for 0-indexed array */
	for (i = 0; i < count; i++) {
		tds[i].ptr = virt_to_phys (&tds[i + 1]) | TD_DEPTH_FIRST;
	}
	tds[count].ptr = 0 | TD_DEPTH_FIRST | TD_TERMINATE;

	tds[0].token = UHCI_SETUP |
		dev->address << TD_DEVADDR_SHIFT |
		endp << TD_EP_SHIFT |
		TD_TOGGLE_DATA0 |
		maxlen(drlen) << TD_MAXLEN_SHIFT;
	tds[0].bufptr = virt_to_phys (devreq);
	tds[0].ctrlsts = (3 << TD_COUNTER_SHIFT) |
		(dev->speed?TD_LOWSPEED:0) |
		TD_STATUS_ACTIVE;

	int toggle = 1;
	for (i = 1; i < count; i++) {
		switch (dir) {
			case SETUP: tds[i].token = UHCI_SETUP; break;
			case IN:    tds[i].token = UHCI_IN;    break;
			case OUT:   tds[i].token = UHCI_OUT;   break;
		}
		tds[i].token |= dev->address << TD_DEVADDR_SHIFT |
			endp << TD_EP_SHIFT |
			maxlen (min (mlen, dalen)) << TD_MAXLEN_SHIFT |
			toggle << TD_TOGGLE_SHIFT;
		tds[i].bufptr = virt_to_phys (data);
		tds[i].ctrlsts = (3 << TD_COUNTER_SHIFT) |
			(dev->speed?TD_LOWSPEED:0) |
			TD_STATUS_ACTIVE;
		toggle ^= 1;
		dalen -= mlen;
		data += mlen;
	}

	tds[count].token = ((dir == OUT) ? UHCI_IN : UHCI_OUT) |
		dev->address << TD_DEVADDR_SHIFT |
		endp << TD_EP_SHIFT |
		maxlen(0) << TD_MAXLEN_SHIFT |
		TD_TOGGLE_DATA1;
	tds[count].bufptr = 0;
	tds[count].ctrlsts = (0 << TD_COUNTER_SHIFT) | /* as Linux 2.4.10 does */
		(dev->speed?TD_LOWSPEED:0) |
		TD_STATUS_ACTIVE;
	UHCI_INST (dev->controller)->qh_data->elementlinkptr =
		virt_to_phys (tds) & ~(FLISTP_QH | FLISTP_TERMINATE);
	td_t *td = wait_for_completed_qh (dev->controller,
					  UHCI_INST (dev->controller)->
					  qh_data);
	int result;
	if (td == 0) {
		result = 0;
	} else {
		usb_debug ("control packet, req %x\n", req);
		td_dump (td);
		result = 1;
	}
	free (tds);
	return result;
}
Esempio n. 4
0
static int
uhci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen,
	      unsigned char *data)
{
	int endp = 0;		/* this is control: always 0 */
	int mlen = dev->endpoints[0].maxpacketsize;
	int count = (2 + (dalen + mlen - 1) / mlen);
	unsigned short req = ((unsigned short *) devreq)[0];
	int i;
	td_t *tds = memalign (16, sizeof (td_t) * count);
	memset (tds, 0, sizeof (td_t) * count);
	count--;		/* to compensate for 0-indexed array */
	for (i = 0; i < count; i++) {
		tds[i].ptr = virt_to_phys (&tds[i + 1]);
		tds[i].depth_first = 1;
		tds[i].terminate = 0;
	}
	tds[count].ptr = 0;
	tds[count].depth_first = 1;
	tds[count].terminate = 1;

	tds[0].pid = UHCI_SETUP;
	tds[0].dev_addr = dev->address;
	tds[0].endp = endp;
	tds[0].maxlen = maxlen (drlen);
	tds[0].counter = 3;
	tds[0].data_toggle = 0;
	tds[0].lowspeed = dev->speed;
	tds[0].bufptr = virt_to_phys (devreq);
	tds[0].status_active = 1;

	int toggle = 1;
	for (i = 1; i < count; i++) {
		switch (dir) {
			case SETUP: tds[i].pid = UHCI_SETUP; break;
			case IN:    tds[i].pid = UHCI_IN;    break;
			case OUT:   tds[i].pid = UHCI_OUT;   break;
		}
		tds[i].dev_addr = dev->address;
		tds[i].endp = endp;
		tds[i].maxlen = maxlen (min (mlen, dalen));
		tds[i].counter = 3;
		tds[i].data_toggle = toggle;
		tds[i].lowspeed = dev->speed;
		tds[i].bufptr = virt_to_phys (data);
		tds[i].status_active = 1;
		toggle ^= 1;
		dalen -= mlen;
		data += mlen;
	}

	tds[count].pid = (dir == OUT) ? UHCI_IN : UHCI_OUT;
	tds[count].dev_addr = dev->address;
	tds[count].endp = endp;
	tds[count].maxlen = maxlen (0);
	tds[count].counter = 0;	/* as per linux 2.4.10 */
	tds[count].data_toggle = 1;
	tds[count].lowspeed = dev->speed;
	tds[count].bufptr = 0;
	tds[count].status_active = 1;
	UHCI_INST (dev->controller)->qh_data->elementlinkptr.ptr =
		virt_to_phys (tds);
	UHCI_INST (dev->controller)->qh_data->elementlinkptr.queue_head = 0;
	UHCI_INST (dev->controller)->qh_data->elementlinkptr.terminate = 0;
	td_t *td = wait_for_completed_qh (dev->controller,
					  UHCI_INST (dev->controller)->
					  qh_data);
	int result;
	if (td == 0) {
		result = 0;
	} else {
		debug ("control packet, req %x\n", req);
		td_dump (td);
		result = 1;
	}
	free (tds);
	return result;
}