Exemplo n.º 1
0
static void dump_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
		     int len, char *str)
{
#if defined(VERBOSE)
	int i;
#endif

	DBG("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d stat:%#lx",
	    str,
	    isp116x_get_current_frame_number(dev),
	    usb_pipedevice(pipe),
	    usb_pipeendpoint(pipe),
	    usb_pipeout(pipe) ? 'O' : 'I',
	    usb_pipetype(pipe) < 2 ?
	    (usb_pipeint(pipe) ?
	     "INTR" : "ISOC") :
	    (usb_pipecontrol(pipe) ? "CTRL" : "BULK"), len, dev->status);
#if defined(VERBOSE)
	if (len > 0 && buffer) {
		printf(__FILE__ ": data(%d):", len);
		for (i = 0; i < 16 && i < len; i++)
			printf(" %02x", ((__u8 *) buffer)[i]);
		printf("%s\n", i < len ? "..." : "");
	}
#endif
}
Exemplo n.º 2
0
static inline void qtd_copy_status (struct urb *urb, size_t length, u32 token)
{
	/* count IN/OUT bytes, not SETUP (even short packets) */
	if (likely (QTD_PID (token) != 2))
		urb->actual_length += length - QTD_LENGTH (token);

	/* don't modify error codes */
	if (unlikely (urb->status == -EINPROGRESS && (token & QTD_STS_HALT))) {
		if (token & QTD_STS_BABBLE) {
			/* FIXME "must" disable babbling device's port too */
			urb->status = -EOVERFLOW;
		} else if (token & QTD_STS_MMF) {
			/* fs/ls interrupt xfer missed the complete-split */
			urb->status = -EPROTO;
		} else if (token & QTD_STS_DBE) {
			urb->status = (QTD_PID (token) == 1) /* IN ? */
				? -ENOSR  /* hc couldn't read data */
				: -ECOMM; /* hc couldn't write data */
		} else if (token & QTD_STS_XACT) {
			/* timeout, bad crc, wrong PID, etc; retried */
			if (QTD_CERR (token))
				urb->status = -EPIPE;
			else {
				dbg ("3strikes");
				urb->status = -EPROTO;
			}
		/* CERR nonzero + no errors + halt --> stall */
		} else if (QTD_CERR (token))
			urb->status = -EPIPE;
		else	/* unknown */
			urb->status = -EPROTO;

		dbg ("ep %d-%s qtd token %08x --> status %d",
			/* devpath */
			usb_pipeendpoint (urb->pipe),
			usb_pipein (urb->pipe) ? "in" : "out",
			token, urb->status);

		/* stall indicates some recovery action is needed */
		if (urb->status == -EPIPE) {
			int	pipe = urb->pipe;

			if (!usb_pipecontrol (pipe))
				usb_endpoint_halt (urb->dev,
					usb_pipeendpoint (pipe),
					usb_pipeout (pipe));
			if (urb->dev->tt && !usb_pipeint (pipe)) {
err ("must CLEAR_TT_BUFFER, hub port %d%s addr %d ep %d",
    urb->dev->ttport, /* devpath */
    urb->dev->tt->multi ? "" : " (all-ports TT)",
    urb->dev->devnum, usb_pipeendpoint (urb->pipe));
				// FIXME something (khubd?) should make the hub
				// CLEAR_TT_BUFFER ASAP, it's blocking other
				// fs/ls requests... hub_tt_clear_buffer() ?
			}
		}
	}
}
Exemplo n.º 3
0
static int dwc_otg_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
				 void *buffer, int txlen,
				 struct devrequest *cmd)
{
	int stat = 0;

	if (usb_pipeint(pipe)) {
		puts("Root-Hub submit IRQ: NOT implemented\n");
		return 0;
	}

	if (cmd->requesttype & USB_DIR_IN)
		stat = dwc_otg_submit_rh_msg_in(dev, buffer, txlen, cmd);
	else
		stat = dwc_otg_submit_rh_msg_out(dev, buffer, txlen, cmd);

	mdelay(1);

	return stat;
}
Exemplo n.º 4
0
void urb_print (urb_t * urb, char * str, int small)
{
	unsigned int pipe= urb->pipe;
	int i, len;

	if (!urb->dev || !urb->dev->bus) {
		dbg("%s URB: no dev", str);
		return;
	}

	printk("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,flags:%4x,len:%d/%d,stat:%d(%x)\n",
			str,
		 	hci_get_current_frame_number (urb->dev),
		 	usb_pipedevice (pipe),
		 	usb_pipeendpoint (pipe),
		 	usb_pipeout (pipe)? 'O': 'I',
		 	usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
		 		(usb_pipecontrol (pipe)? "CTRL": "BULK"),
		 	urb->transfer_flags,
		 	urb->actual_length,
		 	urb->transfer_buffer_length,
		 	urb->status, urb->status);
	if (!small) {
		if (usb_pipecontrol (pipe)) {
			printk ( __FILE__ ": cmd(8):");
			for (i = 0; i < 8 ; i++)
				printk (" %02x", ((__u8 *) urb->setup_packet) [i]);
			printk ("\n");
		}
		if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) {
			printk ( __FILE__ ": data(%d/%d):",
				urb->actual_length,
				urb->transfer_buffer_length);
			len = usb_pipeout (pipe)?
						urb->transfer_buffer_length: urb->actual_length;
			for (i = 0; i < 16 && i < len; i++)
				printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]);
			printk ("%s stat:%d\n", i < len? "...": "", urb->status);
		}
	}
}
Exemplo n.º 5
0
static int hcs_return_urb (hci_t * hci, urb_t * urb, int resub_ok)
{
	int resubmit = 0;
	struct dmaWork* dw=NULL;

	if (urb_debug)
		urb_print (urb, "RET", usb_pipeout (urb->pipe));

  	resubmit = urb->interval && resub_ok;


	if (!resubmit) {
		urb->dev = NULL;
		dw = urb->hcpriv;
		urb->hcpriv = NULL;
	}
	if (urb->complete) {
		if ((!resubmit)||!IntervalStatus(urb)) {
			urb->complete (urb); /* call complete */
		}
	}
	if (resubmit) { /* requeue the URB */
		if (!usb_pipeint (urb->pipe) || (urb->interval==0)) {
			urb->start_frame = hci->frame_no;
			hcs_urb_queue (hci, urb);
		} else {
			urb->start_frame = hci->frame_no + urb->interval;
			list_add (&urb->urb_list, &hci->waiting_intr_list);
			hc116x_enable_sofint(hci);
		}
	} else {
		if (dw) FreeDmaWork(hci,dw);		//this also wakes anyone waiting on its destruction
	}

	return 0;
}
Exemplo n.º 6
0
static int r8a66597_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
			void *buffer, int transfer_len, struct devrequest *cmd)
{
	struct r8a66597 *r8a66597 = &gr8a66597;
	int leni = transfer_len;
	int len = 0;
	int stat = 0;
	__u16 bmRType_bReq;
	__u16 wValue;
	__u16 wLength;
	unsigned char data[32];

	R8A66597_DPRINT("%s\n", __func__);

	if (usb_pipeint(pipe)) {
		printf("Root-Hub submit IRQ: NOT implemented");
		return 0;
	}

	bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
	wValue	      = cpu_to_le16 (cmd->value);
	wLength	      = cpu_to_le16 (cmd->length);

	switch (bmRType_bReq) {
	case RH_GET_STATUS:
		*(__u16 *)buffer = cpu_to_le16(1);
		len = 2;
		break;
	case RH_GET_STATUS | RH_INTERFACE:
		*(__u16 *)buffer = cpu_to_le16(0);
		len = 2;
		break;
	case RH_GET_STATUS | RH_ENDPOINT:
		*(__u16 *)buffer = cpu_to_le16(0);
		len = 2;
		break;
	case RH_GET_STATUS | RH_CLASS:
		*(__u32 *)buffer = cpu_to_le32(0);
		len = 4;
		break;
	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
		*(__u32 *)buffer = cpu_to_le32(r8a66597->port_status |
						(r8a66597->port_change << 16));
		len = 4;
		break;
	case RH_CLEAR_FEATURE | RH_ENDPOINT:
	case RH_CLEAR_FEATURE | RH_CLASS:
		break;

	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
		switch (wValue) {
		case RH_C_PORT_CONNECTION:
			r8a66597->port_change &= ~USB_PORT_STAT_C_CONNECTION;
			break;
		}
		break;

	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
		switch (wValue) {
		case (RH_PORT_SUSPEND):
			break;
		case (RH_PORT_RESET):
			r8a66597_bus_reset(r8a66597, 0);
			break;
		case (RH_PORT_POWER):
			break;
		case (RH_PORT_ENABLE):
			break;
		}
		break;
	case RH_SET_ADDRESS:
		gr8a66597.rh_devnum = wValue;
		break;
	case RH_GET_DESCRIPTOR:
		switch ((wValue & 0xff00) >> 8) {
		case (0x01): /* device descriptor */
			len = min_t(unsigned int,
				  leni,
				  min_t(unsigned int,
				      sizeof(root_hub_dev_des),
				      wLength));
			memcpy(buffer, root_hub_dev_des, len);
			break;
		case (0x02): /* configuration descriptor */
			len = min_t(unsigned int,
				  leni,
				  min_t(unsigned int,
				      sizeof(root_hub_config_des),
				      wLength));
			memcpy(buffer, root_hub_config_des, len);
			break;
		case (0x03): /* string descriptors */
			if (wValue == 0x0300) {
				len = min_t(unsigned int,
					  leni,
					  min_t(unsigned int,
					      sizeof(root_hub_str_index0),
					      wLength));
				memcpy(buffer, root_hub_str_index0, len);
			}
			if (wValue == 0x0301) {
				len = min_t(unsigned int,
					  leni,
					  min_t(unsigned int,
					      sizeof(root_hub_str_index1),
					      wLength));
				memcpy(buffer, root_hub_str_index1, len);
			}
			break;
		default:
			stat = USB_ST_STALLED;
		}
Exemplo n.º 7
0
static vsf_err_t vsfusbh_rh_submit_urb(struct vsfusbh_t *usbh,
		struct vsfusbh_urb_t *vsfurb)
{
	uint16_t typeReq, wValue, wLength;
	struct usb_ctrlrequest_t *cmd = &vsfurb->setup_packet;
	uint32_t pipe = vsfurb->pipe;
	uint8_t data[32];
	uint8_t len = 0;

	if (usb_pipeint(pipe))
	{
		// WARNING: not support int transfer for HUB
		return VSFERR_NOT_SUPPORT;
	}

	vsfurb->actual_length = 0;

	typeReq = (cmd->bRequestType << 8) | cmd->bRequest;
	wValue = cmd->wValue;
	wLength = cmd->wLength;

	if (wLength > vsfurb->transfer_length)
		goto error;

	switch (typeReq)
	{
	case DeviceRequest | USB_REQ_GET_STATUS:
		data[0] = 1;
		data[1] = 0;
		len = 2;
		break;
	case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
	case DeviceOutRequest | USB_REQ_SET_FEATURE:
		break;
	case DeviceRequest | USB_REQ_GET_CONFIGURATION:
		data[0] = 1;
		len = 1;
		break;
	case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
		break;
	case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
		switch (wValue & 0xff00)
		{
		case USB_DT_DEVICE << 8:
			switch (vsfurb->vsfdev->speed)
			{
			case USB_SPEED_LOW:
			case USB_SPEED_FULL:
				memcpy (data, usb11_rh_dev_descriptor, 18);
				break;
			case USB_SPEED_HIGH:
				memcpy (data, usb2_rh_dev_descriptor, 18);
				break;
			//case USB_SPEED_VARIABLE:
			//	break;
			//case USB_SPEED_SUPER:
			//	break;
			default:
				goto error;
			}
			len = 18;
			break;
		case USB_DT_CONFIG << 8:
			switch (vsfurb->vsfdev->speed)
			{
			case USB_SPEED_LOW:
			case USB_SPEED_FULL:
				len = sizeof(fs_rh_config_descriptor);
				memcpy (data, fs_rh_config_descriptor, len);
				break;
			case USB_SPEED_HIGH:
			case USB_SPEED_VARIABLE:
				\
				len = sizeof(hs_rh_config_descriptor);
				memcpy (data, hs_rh_config_descriptor, len);
				break;
			//case USB_SPEED_SUPER:
			//	break;
			default:
				goto error;
			}
			break;
		case USB_DT_STRING << 8:
			goto nongeneric;
		default:
			goto error;
		}
		break;
	case DeviceRequest | USB_REQ_GET_INTERFACE:
		data[0] = 0;
		len = 1;
		break;
	case DeviceOutRequest | USB_REQ_SET_INTERFACE:
		break;
	case DeviceOutRequest | USB_REQ_SET_ADDRESS:
		break;
	case EndpointRequest | USB_REQ_GET_STATUS:
		data[0] = 0;
		data[1] = 0;
		len = 2;
		break;
	case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
	case EndpointOutRequest | USB_REQ_SET_FEATURE:
		break;
	default:
nongeneric:
		return usbh->hcd->rh_control(usbh->hcd_data, vsfurb);
	}

	if (len)
	{
		if (vsfurb->transfer_length < len)
			len = vsfurb->transfer_length;
		vsfurb->actual_length = len;

		memcpy (vsfurb->transfer_buffer, data, len);
	}
	vsfurb->status = URB_OK;

	vsfsm_post_evt_pending(vsfurb->sm, VSFSM_EVT_URB_COMPLETE);
	return VSFERR_NONE;

error:
	vsfurb->status = URB_FAIL;
	return VSFERR_FAIL;
}
Exemplo n.º 8
0
/*
 * This function handles all USB request to the the virtual root hub
 */
static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe,
			       void *data, int buf_len, struct devrequest *cmd)
{
	__u8 data_buf[16];
	__u8 *bufp = data_buf;
	int len = 0;
	int status = 0;
	__u16 bmRType_bReq;
	__u16 wValue  = le16_to_cpu (cmd->value);
	__u16 wLength = le16_to_cpu (cmd->length);
#ifdef SL811_DEBUG
	__u16 wIndex  = le16_to_cpu (cmd->index);
#endif

	if (usb_pipeint(pipe)) {
		PDEBUG(0, "interrupt transfer unimplemented!\n");
		return 0;
	}

	bmRType_bReq  = cmd->requesttype | (cmd->request << 8);

	PDEBUG(5, "submit rh urb, req = %d(%x) val = %#x index = %#x len=%d\n",
	       bmRType_bReq, bmRType_bReq, wValue, wIndex, wLength);

	/* Request Destination:
		   without flags: Device,
		   USB_RECIP_INTERFACE: interface,
		   USB_RECIP_ENDPOINT: endpoint,
		   USB_TYPE_CLASS means HUB here,
		   USB_RECIP_OTHER | USB_TYPE_CLASS  almost ever means HUB_PORT here
	*/
	switch (bmRType_bReq) {
	case RH_GET_STATUS:
		*(__u16 *)bufp = cpu_to_le16(1);
		OK(2);

	case RH_GET_STATUS | USB_RECIP_INTERFACE:
		*(__u16 *)bufp = cpu_to_le16(0);
		OK(2);

	case RH_GET_STATUS | USB_RECIP_ENDPOINT:
		*(__u16 *)bufp = cpu_to_le16(0);
		OK(2);

	case RH_GET_STATUS | USB_TYPE_CLASS:
		*(__u32 *)bufp = cpu_to_le32(0);
		OK(4);

	case RH_GET_STATUS | USB_RECIP_OTHER | USB_TYPE_CLASS:
		*(__u32 *)bufp = cpu_to_le32(rh_status.wPortChange<<16 | rh_status.wPortStatus);
		OK(4);

	case RH_CLEAR_FEATURE | USB_RECIP_ENDPOINT:
		switch (wValue) {
		case 1:
			OK(0);
		}
		break;

	case RH_CLEAR_FEATURE | USB_TYPE_CLASS:
		switch (wValue) {
		case C_HUB_LOCAL_POWER:
			OK(0);

		case C_HUB_OVER_CURRENT:
			OK(0);
		}
		break;

	case RH_CLEAR_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
		switch (wValue) {
		case USB_PORT_FEAT_ENABLE:
			rh_status.wPortStatus &= ~USB_PORT_STAT_ENABLE;
			OK(0);

		case USB_PORT_FEAT_SUSPEND:
			rh_status.wPortStatus &= ~USB_PORT_STAT_SUSPEND;
			OK(0);

		case USB_PORT_FEAT_POWER:
			rh_status.wPortStatus &= ~USB_PORT_STAT_POWER;
			OK(0);

		case USB_PORT_FEAT_C_CONNECTION:
			rh_status.wPortChange &= ~USB_PORT_STAT_C_CONNECTION;
			OK(0);

		case USB_PORT_FEAT_C_ENABLE:
			rh_status.wPortChange &= ~USB_PORT_STAT_C_ENABLE;
			OK(0);

		case USB_PORT_FEAT_C_SUSPEND:
			rh_status.wPortChange &= ~USB_PORT_STAT_C_SUSPEND;
			OK(0);

		case USB_PORT_FEAT_C_OVER_CURRENT:
			rh_status.wPortChange &= ~USB_PORT_STAT_C_OVERCURRENT;
			OK(0);

		case USB_PORT_FEAT_C_RESET:
			rh_status.wPortChange &= ~USB_PORT_STAT_C_RESET;
			OK(0);
		}
		break;

	case RH_SET_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
		switch (wValue) {
		case USB_PORT_FEAT_SUSPEND:
			rh_status.wPortStatus |= USB_PORT_STAT_SUSPEND;
			OK(0);

		case USB_PORT_FEAT_RESET:
			rh_status.wPortStatus |= USB_PORT_STAT_RESET;
			rh_status.wPortChange = 0;
			rh_status.wPortChange |= USB_PORT_STAT_C_RESET;
			rh_status.wPortStatus &= ~USB_PORT_STAT_RESET;
			rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
			OK(0);

		case USB_PORT_FEAT_POWER:
			rh_status.wPortStatus |= USB_PORT_STAT_POWER;
			OK(0);

		case USB_PORT_FEAT_ENABLE:
			rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
			OK(0);
		}
		break;

	case RH_SET_ADDRESS:
		root_hub_devnum = wValue;
		OK(0);

	case RH_GET_DESCRIPTOR:
		switch ((wValue & 0xff00) >> 8) {
		case USB_DT_DEVICE:
			len = sizeof(sl811_rh_dev_des);
			bufp = sl811_rh_dev_des;
			OK(len);

		case USB_DT_CONFIG:
			len = sizeof(sl811_rh_config_des);
			bufp = sl811_rh_config_des;
			OK(len);

		case USB_DT_STRING:
			len = usb_root_hub_string(wValue & 0xff, (int)(long)0,	"SL811HS", data, wLength);
			if (len > 0) {
				bufp = data;
				OK(len);
			}

		default:
			status = -32;
		}
		break;

	case RH_GET_DESCRIPTOR | USB_TYPE_CLASS:
		len = sizeof(sl811_rh_hub_des);
		bufp = sl811_rh_hub_des;
		OK(len);

	case RH_GET_CONFIGURATION:
		bufp[0] = 0x01;
		OK(1);

	case RH_SET_CONFIGURATION:
		OK(0);

	default:
		PDEBUG(1, "unsupported root hub command\n");
		status = -32;
	}

	len = min(len, buf_len);
	if (data != bufp)
		memcpy(data, bufp, len);

	PDEBUG(5, "len = %d, status = %d\n", len, status);

	usb_dev->status = status;
	usb_dev->act_len = len;

	return status == 0 ? len : status;
}
Exemplo n.º 9
0
static int dwc_otg_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
				 void *buffer, int transfer_len,
				 struct devrequest *cmd)
{
	int leni = transfer_len;
	int len = 0;
	int stat = 0;
	__u16 bmRType_bReq;
	__u16 wValue;
	__u16 wLength;
	unsigned char data[32];
	hprt0_data_t hprt0 = {.d32 = 0 };

	if (usb_pipeint(pipe)) {
		printf("Root-Hub submit IRQ: NOT implemented");
		return 0;
	}

	bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
	wValue	      = cpu_to_le16 (cmd->value);
	wLength	      = cpu_to_le16 (cmd->length);

	switch (bmRType_bReq) {
	case RH_GET_STATUS:
		*(__u16 *)buffer = cpu_to_le16(1);
		len = 2;
		break;
	case RH_GET_STATUS | RH_INTERFACE:
		*(__u16 *)buffer = cpu_to_le16(0);
		len = 2;
		break;
	case RH_GET_STATUS | RH_ENDPOINT:
		*(__u16 *)buffer = cpu_to_le16(0);
		len = 2;
		break;
	case RH_GET_STATUS | RH_CLASS:
		*(__u32 *)buffer = cpu_to_le32(0);
		len = 4;
		break;
	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
		{
			uint32_t port_status = 0;
			uint32_t port_change = 0;
			hprt0.d32 = dwc_read_reg32(g_core_if.host_if->hprt0);
			if (hprt0.b.prtconnsts)
				port_status |= USB_PORT_STAT_CONNECTION;
			if (hprt0.b.prtena)
				port_status |= USB_PORT_STAT_ENABLE;
			if (hprt0.b.prtsusp)
				port_status |= USB_PORT_STAT_SUSPEND;
			if (hprt0.b.prtovrcurract)
				port_status |= USB_PORT_STAT_OVERCURRENT;
			if (hprt0.b.prtrst)
				port_status |= USB_PORT_STAT_RESET;
			if (hprt0.b.prtpwr)
				port_status |= USB_PORT_STAT_POWER;

			port_status |= USB_PORT_STAT_HIGH_SPEED;

			if (hprt0.b.prtenchng)
				port_change |= USB_PORT_STAT_C_ENABLE;
			if (hprt0.b.prtconndet)
				port_change |= USB_PORT_STAT_C_CONNECTION;
			if (hprt0.b.prtovrcurrchng)
				port_change |= USB_PORT_STAT_C_OVERCURRENT;

			*(__u32 *)buffer = cpu_to_le32(port_status |
						(port_change << 16));
			len = 4;
		}
		break;
	case RH_CLEAR_FEATURE | RH_ENDPOINT:
	case RH_CLEAR_FEATURE | RH_CLASS:
		break;

	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
		switch (wValue) {
		case RH_C_PORT_CONNECTION:
			hprt0.d32 = dwc_read_reg32(g_core_if.host_if->hprt0);
			hprt0.b.prtconndet = 1;
			dwc_write_reg32(g_core_if.host_if->hprt0, hprt0.d32);
			break;
		}
		break;

	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
		switch (wValue) {
		case (RH_PORT_SUSPEND):
			break;

		case (RH_PORT_RESET):
			hprt0.d32 = dwc_otg_read_hprt0(&g_core_if);
			hprt0.b.prtrst = 1;
			dwc_write_reg32(g_core_if.host_if->hprt0, hprt0.d32);
			mdelay(50);
			hprt0.b.prtrst = 0;
			dwc_write_reg32(g_core_if.host_if->hprt0, hprt0.d32);

			break;

		case (RH_PORT_POWER):
			hprt0.d32 = dwc_otg_read_hprt0(&g_core_if);
			hprt0.b.prtpwr = 1;
			dwc_write_reg32(g_core_if.host_if->hprt0, hprt0.d32);
			break;

		case (RH_PORT_ENABLE):
			break;
		}
		break;
	case RH_SET_ADDRESS:
		root_hub_devnum = wValue;
		break;
	case RH_GET_DESCRIPTOR:
		switch ((wValue & 0xff00) >> 8) {
		case (0x01): /* device descriptor */
			len = min_t(unsigned int,
				  leni,
				  min_t(unsigned int,
				      sizeof(root_hub_dev_des),
				      wLength));
			memcpy(buffer, root_hub_dev_des, len);
			break;
		case (0x02): /* configuration descriptor */
			len = min_t(unsigned int,
				  leni,
				  min_t(unsigned int,
				      sizeof(root_hub_config_des),
				      wLength));
			memcpy(buffer, root_hub_config_des, len);
			break;
		case (0x03): /* string descriptors */
			if (wValue == 0x0300) {
				len = min_t(unsigned int,
					  leni,
					  min_t(unsigned int,
					      sizeof(root_hub_str_index0),
					      wLength));
				memcpy(buffer, root_hub_str_index0, len);
			}
			if (wValue == 0x0301) {
				len = min_t(unsigned int,
					  leni,
					  min_t(unsigned int,
					      sizeof(root_hub_str_index1),
					      wLength));
				memcpy(buffer, root_hub_str_index1, len);
			}
			break;
		default:
			stat = USB_ST_STALLED;
		}
		break;

	case RH_GET_DESCRIPTOR | RH_CLASS:
	{
		__u32 temp = 0x00000001;

		data[0] = 9;		/* min length; */
		data[1] = 0x29;
		data[2] = temp & RH_A_NDP;
		data[3] = 0;
		if (temp & RH_A_PSM)
			data[3] |= 0x1;
		if (temp & RH_A_NOCP)
			data[3] |= 0x10;
		else if (temp & RH_A_OCPM)
			data[3] |= 0x8;

		/* corresponds to data[4-7] */
		data[5] = (temp & RH_A_POTPGT) >> 24;
		data[7] = temp & RH_B_DR;
		if (data[2] < 7) {
			data[8] = 0xff;
		} else {
			data[0] += 2;
			data[8] = (temp & RH_B_DR) >> 8;
			data[10] = data[9] = 0xff;
		}

		len = min_t(unsigned int, leni,
			    min_t(unsigned int, data[0], wLength));
		memcpy(buffer, data, len);
		break;
	}

	case RH_GET_CONFIGURATION:
		*(__u8 *) buffer = 0x01;
		len = 1;
		break;
	case RH_SET_CONFIGURATION:
		break;
	default:
		printf("unsupported root hub command\n");
		stat = USB_ST_STALLED;
	}
Exemplo n.º 10
0
/*
  Set up PTD's.
*/
static void prepare_ptd(struct isp1362_hcd *isp1362_hcd, struct urb *urb,
			struct isp1362_ep *ep, struct isp1362_ep_queue *epq,
			u16 fno)
{
	struct ptd *ptd;
	int toggle;
	int dir;
	u16 len;
	size_t buf_len = urb->transfer_buffer_length - urb->actual_length;

	DBG(3, "%s: %s ep %p\n", __func__, epq->name, ep);

	ptd = &ep->ptd;

	ep->data = (unsigned char *)urb->transfer_buffer + urb->actual_length;

	switch (ep->nextpid) {
	case USB_PID_IN:
		toggle = usb_gettoggle(urb->dev, ep->epnum, 0);
		dir = PTD_DIR_IN;
		if (usb_pipecontrol(urb->pipe)) {
			len = min_t(size_t, ep->maxpacket, buf_len);
		} else if (usb_pipeisoc(urb->pipe)) {
			len = min_t(size_t, urb->iso_frame_desc[fno].length, MAX_XFER_SIZE);
			ep->data = urb->transfer_buffer + urb->iso_frame_desc[fno].offset;
		} else
			len = max_transfer_size(epq, buf_len, ep->maxpacket);
		DBG(1, "%s: IN    len %d/%d/%d from URB\n", __func__, len, ep->maxpacket,
		    (int)buf_len);
		break;
	case USB_PID_OUT:
		toggle = usb_gettoggle(urb->dev, ep->epnum, 1);
		dir = PTD_DIR_OUT;
		if (usb_pipecontrol(urb->pipe))
			len = min_t(size_t, ep->maxpacket, buf_len);
		else if (usb_pipeisoc(urb->pipe))
			len = min_t(size_t, urb->iso_frame_desc[0].length, MAX_XFER_SIZE);
		else
			len = max_transfer_size(epq, buf_len, ep->maxpacket);
		if (len == 0)
			pr_info("%s: Sending ZERO packet: %d\n", __func__,
			     urb->transfer_flags & URB_ZERO_PACKET);
		DBG(1, "%s: OUT   len %d/%d/%d from URB\n", __func__, len, ep->maxpacket,
		    (int)buf_len);
		break;
	case USB_PID_SETUP:
		toggle = 0;
		dir = PTD_DIR_SETUP;
		len = sizeof(struct usb_ctrlrequest);
		DBG(1, "%s: SETUP len %d\n", __func__, len);
		ep->data = urb->setup_packet;
		break;
	case USB_PID_ACK:
		toggle = 1;
		len = 0;
		dir = (urb->transfer_buffer_length && usb_pipein(urb->pipe)) ?
			PTD_DIR_OUT : PTD_DIR_IN;
		DBG(1, "%s: ACK   len %d\n", __func__, len);
		break;
	default:
		toggle = dir = len = 0;
		pr_err("%s@%d: ep->nextpid %02x\n", __func__, __LINE__, ep->nextpid);
		BUG_ON(1);
	}

	ep->length = len;
	if (!len)
		ep->data = NULL;

	ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK | PTD_TOGGLE(toggle);
	ptd->mps = PTD_MPS(ep->maxpacket) | PTD_SPD(urb->dev->speed == USB_SPEED_LOW) |
		PTD_EP(ep->epnum);
	ptd->len = PTD_LEN(len) | PTD_DIR(dir);
	ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe));

	if (usb_pipeint(urb->pipe)) {
		ptd->faddr |= PTD_SF_INT(ep->branch);
		ptd->faddr |= PTD_PR(ep->interval ? __ffs(ep->interval) : 0);
	}
	if (usb_pipeisoc(urb->pipe))
		ptd->faddr |= PTD_SF_ISO(fno);

	DBG(1, "%s: Finished\n", __func__);
}
Exemplo n.º 11
0
/***************************************************************************
 * Function Name : rh_submit_urb
 * 
 * This function handles all USB request to the the virtual root hub
 * 
 * Input: urb = USB request block 
 *
 * Return: 0  
 **************************************************************************/
static int rh_submit_urb (struct urb * urb)
{
	struct usb_device *usb_dev = urb->dev;
	hci_t *hci = usb_dev->bus->hcpriv;
	unsigned int pipe = urb->pipe;
	struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) urb->setup_packet;
	void *data = urb->transfer_buffer;
	int leni = urb->transfer_buffer_length;
	int len = 0;
	int status = TD_CC_NOERROR;
	__u32 datab[4];
	__u8 *data_buf = (__u8 *) datab;

	__u16 bmRType_bReq;
	__u16 wValue;
	__u16 wIndex;
	__u16 wLength;

	DBGFUNC ("enter rh_submit_urb\n");
	if (usb_pipeint (pipe)) {
		hci->rh.urb = urb;
		hci->rh.send = 1;
		hci->rh.interval = urb->interval;
		rh_init_int_timer (urb);
		urb->status = cc_to_error (TD_CC_NOERROR);

		return 0;
	}

	bmRType_bReq = cmd->bRequestType | (cmd->bRequest << 8);
	wValue = le16_to_cpu (cmd->wValue);
	wIndex = le16_to_cpu (cmd->wIndex);
	wLength = le16_to_cpu (cmd->wLength);

	DBG ("rh_submit_urb, req = %d(%x) len=%d",
	     bmRType_bReq, bmRType_bReq, wLength);

	switch (bmRType_bReq) {
		/* Request Destination:
		   without flags: Device, 
		   RH_INTERFACE: interface, 
		   RH_ENDPOINT: endpoint,
		   RH_CLASS means HUB here, 
		   RH_OTHER | RH_CLASS  almost ever means HUB_PORT here 
		 */

	case RH_GET_STATUS:
		*(__u16 *) data_buf = cpu_to_le16 (1);
		OK (2);

	case RH_GET_STATUS | RH_INTERFACE:
		*(__u16 *) data_buf = cpu_to_le16 (0);
		OK (2);

	case RH_GET_STATUS | RH_ENDPOINT:
		*(__u16 *) data_buf = cpu_to_le16 (0);
		OK (2);

	case RH_GET_STATUS | RH_CLASS:
		*(__u32 *) data_buf = cpu_to_le32 (0);
		OK (4);

	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
		*(__u32 *) data_buf =
		    cpu_to_le32 (getPortStatusAndChange (hci));
		OK (4);

	case RH_CLEAR_FEATURE | RH_ENDPOINT:
		switch (wValue) {
		case (RH_ENDPOINT_STALL):
			OK (0);
		}
		break;

	case RH_CLEAR_FEATURE | RH_CLASS:
		switch (wValue) {
		case RH_C_HUB_LOCAL_POWER:
			OK (0);

		case (RH_C_HUB_OVER_CURRENT):
			/* Over Current Not Implemented */
			OK (0);
		}
		break;

	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
		switch (wValue) {
		case (RH_PORT_ENABLE):
			clrPortStatus (hci, PORT_ENABLE_STAT);
			OK (0);

		case (RH_PORT_SUSPEND):
			clrPortStatus (hci, PORT_SUSPEND_STAT);
			OK (0);

		case (RH_PORT_POWER):
			clrPortStatus (hci, PORT_POWER_STAT);
			OK (0);

		case (RH_C_PORT_CONNECTION):
			clrPortChange (hci, PORT_CONNECT_STAT);
			OK (0);

		case (RH_C_PORT_ENABLE):
			clrPortChange (hci, PORT_ENABLE_STAT);
			OK (0);

		case (RH_C_PORT_SUSPEND):
			clrPortChange (hci, PORT_SUSPEND_STAT);
			OK (0);

		case (RH_C_PORT_OVER_CURRENT):
			clrPortChange (hci, PORT_OVER_CURRENT_STAT);
			OK (0);

		case (RH_C_PORT_RESET):
			clrPortChange (hci, PORT_RESET_STAT);
			OK (0);
		}
		break;

	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
		switch (wValue) {
		case (RH_PORT_SUSPEND):
			setPortStatus (hci, PORT_SUSPEND_STAT);
			OK (0);

		case (RH_PORT_RESET):
			setPortStatus (hci, PORT_RESET_STAT);
			// USBReset(hci);
			clrPortChange (hci,
				       PORT_CONNECT_CHANGE | PORT_ENABLE_CHANGE
				       | PORT_SUSPEND_CHANGE |
				       PORT_OVER_CURRENT_CHANGE);
			setPortChange (hci, PORT_RESET_CHANGE);
			clrPortStatus (hci, PORT_RESET_STAT);
			setPortStatus (hci, PORT_ENABLE_STAT);

			OK (0);

		case (RH_PORT_POWER):
			setPortStatus (hci, PORT_POWER_STAT);
			OK (0);

		case (RH_PORT_ENABLE):
			setPortStatus (hci, PORT_ENABLE_STAT);
			OK (0);
		}
		break;

	case RH_SET_ADDRESS:
		hci->rh.devnum = wValue;
		OK (0);

	case RH_GET_DESCRIPTOR:
		DBGVERBOSE ("rh_submit_urb: RH_GET_DESCRIPTOR, wValue = 0x%x\n", wValue);
		switch ((wValue & 0xff00) >> 8) {
		case (0x01):	/* device descriptor */
			len = min (leni, min ((__u16)sizeof (root_hub_dev_des), wLength));
			data_buf = root_hub_dev_des;
			OK (len);

		case (0x02):	/* configuration descriptor */
			len = min (leni, min ((__u16)sizeof (root_hub_config_des), wLength));
			data_buf = root_hub_config_des;
			OK (len);

		case (0x03):	/* string descriptors */
			len = root_hub_string (wValue & 0xff, (int) (long) 0,
						   "SL811HS", data, wLength);
			if (len > 0) {
				data_buf = data;
				OK (min (leni, len));
			}

		default:
			status = SL11H_STATMASK_STALL;
		}
		break;

	case RH_GET_DESCRIPTOR | RH_CLASS:
		data_buf[0] = 9;	// min length;
		data_buf[1] = 0x29;
		data_buf[2] = 1;	// # of downstream port
		data_buf[3] = 0;
		datab[1] = 0;
		data_buf[5] = 50;	// 100 ms for port reset
		data_buf[7] = 0xfc;	// which port is attachable
		if (data_buf[2] < 7) {
			data_buf[8] = 0xff;
		} else {
		}

		len = min (leni, min ((__u16)data_buf[0], wLength));
		OK (len);

	case RH_GET_CONFIGURATION:
		*(__u8 *) data_buf = 0x01;
		OK (1);

	case RH_SET_CONFIGURATION:
		OK (0);

	default:
		DBGERR ("unsupported root hub command");
		status = SL11H_STATMASK_STALL;
	}

	len = min (len, leni);
	if (data != data_buf)
		memcpy (data, data_buf, len);
	urb->actual_length = len;
	urb->status = cc_to_error (status);

	urb->hcpriv = NULL;
	urb->dev = NULL;
	if (urb->complete) {
		urb->complete (urb, NULL);
	}

	return 0;
}
Exemplo n.º 12
0
int32 USBHost::aranym_submit_rh_msg(uint32 pipe, memptr buffer, int32 transfer_len,
				    devrequest *cmd)
{
	D(bug("USBHost: aranym_submit_rh_msg()"));

	int32 leni = transfer_len;
	int32 len = 0;
	uint32 datab[4];
	uint8 *data_buf = (uint8 *) datab;
	int32 stat = 0;

	uint16 bmRType_bReq;
	uint16 wValue;
	uint16 wIndex;
	uint16 wLength;

	if (usb_pipeint(pipe)) {
		D(bug("USBHost: Root-Hub submit IRQ: NOT implemented"));
		return -1;
	}

	bmRType_bReq = cmd->requesttype | (cmd->request << 8);
	wValue = cmd->value;
	wIndex = cmd->index;
	wLength = cmd->length;

	D(bug("USBHost: --- HUB ----------------------------------------"));
	D(bug("USBHost: submit rh urb, req=%x val=%#x index=%#x len=%d",
	    bmRType_bReq, wValue, wIndex, wLength));
	D(bug("USBHost: ------------------------------------------------"));

	switch (bmRType_bReq) {
		case RH_GET_STATUS:
			D(bug("USBHost: RH_GET_STATUS"));

			*data_buf = (SDL_BYTEORDER == SDL_BIG_ENDIAN) ? 
					(uint16) SDL_Swap16(1) : (uint16)(1) ;
			len = 2;
			break;

		case RH_GET_STATUS | RH_INTERFACE:
			D(bug("USBHost: RH_GET_STATUS | RH_INTERFACE"));

			*data_buf = (SDL_BYTEORDER == SDL_BIG_ENDIAN) ? 
					(uint16) SDL_Swap16(0) : (uint16)(0) ;
			len = 2;
			break;

		case RH_GET_STATUS | RH_ENDPOINT:
			D(bug("USBHost: RH_GET_STATUS | RH_ENDPOINT"));

			*data_buf = (SDL_BYTEORDER == SDL_BIG_ENDIAN) ? 
					(uint16) SDL_Swap16(0) : (uint16)(0) ;
			len = 2;
			break;

		case RH_GET_STATUS | RH_CLASS:
			D(bug("USBHost: RH_GET_STATUS | RH_CLASS"));

			data_buf = root_hub_class_st;
			len = 4;
			break;

		case RH_GET_STATUS | RH_OTHER | RH_CLASS:
			D(bug("USBHost: RH_GET_STATUS | RH_OTHER | RH_CLASS"));
		
			*(uint32 *)data_buf = (SDL_BYTEORDER == SDL_BIG_ENDIAN) ? 
						SDL_Swap32(port_status[wIndex - 1]) :
						port_status[wIndex - 1];
			len = 4;
			break;

		case RH_CLEAR_FEATURE | RH_ENDPOINT:
			D(bug("USBHost: RH_CLEAR_FEATURE | RH_ENDPOINT"));

			switch (wValue) {
				case RH_ENDPOINT_STALL:
					D(bug("USBHost: C_HUB_ENDPOINT_STALL"));

					len = 0;
					break;
			}
			break;

		case RH_CLEAR_FEATURE | RH_CLASS:
			D(bug("USBHost: RH_CLEAR_FEATURE | RH_CLASS"));

			switch (wValue) {
				case RH_C_HUB_LOCAL_POWER:
					D(bug("USBHost: C_HUB_LOCAL_POWER"));

					len = 0;
					break;

				case RH_C_HUB_OVER_CURRENT:
					D(bug("USBHost: C_HUB_OVER_CURRENT"));

					len = 0;
					break;
			}
			break;

		case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
			D(bug("USBHost: RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS"));

			switch (wValue) {
				case RH_PORT_ENABLE:
					port_status[wIndex - 1] &= ~RH_PS_PES;
					len = 0;
					break;

				case RH_PORT_SUSPEND:
					port_status[wIndex - 1] |= RH_PS_PSS;
					len = 0;
					break;

				case RH_PORT_POWER:
				
					len = 0;
					break;

				case RH_C_PORT_CONNECTION:
					port_status[wIndex - 1] &= ~RH_PS_CSC;
					len = 0;
					break;

				case RH_C_PORT_ENABLE:
					port_status[wIndex - 1] &= ~RH_PS_PESC;
					len = 0;
					break;

				case RH_C_PORT_SUSPEND:

					len = 0;
					break;

				case RH_C_PORT_OVER_CURRENT:
					port_status[wIndex - 1] &= ~RH_PS_OCIC;
					len = 0;
					break;

				case RH_C_PORT_RESET:
					port_status[wIndex - 1] &= ~RH_PS_PRSC;
					len = 0;
					break;

				default:
					D(bug("USBHost: invalid wValue"));
					stat = USB_ST_STALLED;
			}
			break;

		case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
			D(bug("USBHost: RH_SET_FEATURE | RH_OTHER | RH_CLASS"));

			switch (wValue) {
				case RH_PORT_SUSPEND:

					len = 0;
					break;

				case RH_PORT_RESET:
					port_status[wIndex - 1] |= RH_PS_PRS;
					len = 0;
					break;

				case RH_PORT_POWER:
					port_status[wIndex - 1] |= RH_PS_PPS;
					len = 0;
					break;

				case RH_PORT_ENABLE:

					len = 0;
					break;

				default:
					D(bug("USBHost: invalid wValue"));
					stat = USB_ST_STALLED;
			}
			break;

		case RH_SET_ADDRESS:
			D(bug("USBHost: RH_SET_ADDRESS"));

			rh_devnum = wValue;
			len = 0;
			break;

		case RH_GET_DESCRIPTOR:
			D(bug("USBHost: RH_GET_DESCRIPTOR: %x, %d", wValue, wLength));

			switch (wValue) {
				case (USB_DT_DEVICE << 8):	/* device descriptor */
					len = min1_t(uint32,
				    	     	     leni, min2_t(uint32,
						     		  sizeof(root_hub_dev_des),
					      		  	  wLength));
					data_buf = root_hub_dev_des;
					break;

				case (USB_DT_CONFIG << 8):	/* configuration descriptor */
					len = min1_t(uint32,
						     leni, min2_t(uint32,
								  sizeof(root_hub_config_des),
								  wLength));
					data_buf = root_hub_config_des;
					break;

				case ((USB_DT_STRING << 8) | 0x00):	/* string 0 descriptors */
					len = min1_t(uint32,
						     leni, min2_t(uint32,
								  sizeof(root_hub_str_index0),
								  wLength));
					data_buf = root_hub_str_index0;
					break;

				case ((USB_DT_STRING << 8) | 0x01):	/* string 1 descriptors */
					len = min1_t(uint32,
						     leni, min2_t(uint32,
								  sizeof(root_hub_str_index1),
								  wLength));
					data_buf = root_hub_str_index1;
					break;

				default:
					D(bug("USBHost: invalid wValue"));

					stat = USB_ST_STALLED;
			}
			break;

		case RH_GET_DESCRIPTOR | RH_CLASS:
			D(bug("USBHost: RH_GET_DESCRIPTOR | RH_CLASS"));

			data_buf = root_hub_class_des;
			len = min1_t(uint32, leni,
				    min2_t(uint32, data_buf[0], wLength));
			break;

		case RH_GET_CONFIGURATION:
			D(bug("USBHost: RH_GET_CONFIGURATION"));

			*(uint8 *) data_buf = 0x01;
			len = 1;
			break;

		case RH_SET_CONFIGURATION:
			D(bug("USBHost: RH_SET_CONFIGURATION"));

			len = 0;
			break;

		default:
			D(bug("USBHost: *** *** *** unsupported root hub command *** *** ***"));
			stat = USB_ST_STALLED;
	}

	len = min1_t(int32, len, leni);

	if(buffer != 0)
		Host2Atari_memcpy(buffer, data_buf, len);

	return (stat ? -1 : len);
}