⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb.c

📁 linux下安装无线网卡启动的程式
💻 C
📖 第 1 页 / 共 3 页
字号:
					       urb->actual_length);			}			NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS;			irp->io_status.status = STATUS_SUCCESS;			break;		case -ENOENT:		case -ECONNRESET:			/* urb canceled */			irp->io_status.info = 0;			TRACE2("urb %p canceled", urb);			NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS;			irp->io_status.status = STATUS_CANCELLED;			break;		default:			TRACE2("irp: %p, urb: %p, status: %d/%d",				 irp, urb, urb->status, wrap_urb->state);			irp->io_status.info = 0;			NT_URB_STATUS(nt_urb) = wrap_urb_status(urb->status);			irp->io_status.status =				nt_urb_irp_status(NT_URB_STATUS(nt_urb));			break;		}		wrap_free_urb(urb);		IoCompleteRequest(irp, IO_NO_INCREMENT);	}	USBEXIT(return);}static USBD_STATUS wrap_bulk_or_intr_trans(struct irp *irp){	usbd_pipe_handle pipe_handle;	struct urb *urb;	unsigned int pipe;	struct usbd_bulk_or_intr_transfer *bulk_int_tx;	USBD_STATUS status;	struct usb_device *udev;	union nt_urb *nt_urb;	nt_urb = IRP_URB(irp);	udev = IRP_WRAP_DEVICE(irp)->usb.udev;	bulk_int_tx = &nt_urb->bulk_int_transfer;	pipe_handle = bulk_int_tx->pipe_handle;	USBTRACE("flags: 0x%x, length: %u, buffer: %p, handle: %p",		 bulk_int_tx->transfer_flags,		 bulk_int_tx->transfer_buffer_length,		 bulk_int_tx->transfer_buffer, pipe_handle);	if (USBD_IS_BULK_PIPE(pipe_handle)) {		if (bulk_int_tx->transfer_flags & USBD_TRANSFER_DIRECTION_IN)			pipe = usb_rcvbulkpipe(udev,					       pipe_handle->bEndpointAddress);		else			pipe = usb_sndbulkpipe(udev,					       pipe_handle->bEndpointAddress);	} else {		if (bulk_int_tx->transfer_flags & USBD_TRANSFER_DIRECTION_IN)			pipe = usb_rcvintpipe(udev,					      pipe_handle->bEndpointAddress);		else			pipe = usb_sndintpipe(udev,					      pipe_handle->bEndpointAddress);	}	DUMP_IRP(irp);	urb = wrap_alloc_urb(irp, pipe, bulk_int_tx->transfer_buffer,			     bulk_int_tx->transfer_buffer_length);	if (!urb) {		ERROR("couldn't allocate urb");		return USBD_STATUS_NO_MEMORY;	}	if (usb_pipein(pipe) &&	    (!(bulk_int_tx->transfer_flags & USBD_SHORT_TRANSFER_OK))) {		USBTRACE("short not ok");		urb->transfer_flags |= URB_SHORT_NOT_OK;	}	if (usb_pipebulk(pipe)) {		usb_fill_bulk_urb(urb, udev, pipe, urb->transfer_buffer,				  bulk_int_tx->transfer_buffer_length,				  wrap_urb_complete, urb->context);		USBTRACE("submitting bulk urb %p on pipe 0x%x (ep 0x%x)",			 urb, urb->pipe, pipe_handle->bEndpointAddress);	} else {		usb_fill_int_urb(urb, udev, pipe, urb->transfer_buffer,				 bulk_int_tx->transfer_buffer_length,				 wrap_urb_complete, urb->context,				 pipe_handle->bInterval);		USBTRACE("submitting interrupt urb %p on pipe 0x%x (ep 0x%x), "			 "intvl: %d", urb, urb->pipe,			 pipe_handle->bEndpointAddress, pipe_handle->bInterval);	}	status = wrap_submit_urb(irp);	USBTRACE("status: %08X", status);	USBEXIT(return status);}static USBD_STATUS wrap_vendor_or_class_req(struct irp *irp){	u8 req_type;	unsigned int pipe;	struct usbd_vendor_or_class_request *vc_req;	struct usb_device *udev;	union nt_urb *nt_urb;	USBD_STATUS status;	struct urb *urb;	struct usb_ctrlrequest *dr;	nt_urb = IRP_URB(irp);	udev = IRP_WRAP_DEVICE(irp)->usb.udev;	vc_req = &nt_urb->vendor_class_request;	USBTRACE("bits: %x, req: %x, val: %08x, index: %08x, flags: %x,"		 "buf: %p, len: %d", vc_req->reserved_bits, vc_req->request,		 vc_req->value, vc_req->index, vc_req->transfer_flags,		 vc_req->transfer_buffer, vc_req->transfer_buffer_length);	USBTRACE("%x", nt_urb->header.function);	switch (nt_urb->header.function) {	case URB_FUNCTION_VENDOR_DEVICE:		req_type = USB_TYPE_VENDOR | USB_RECIP_DEVICE;		break;	case URB_FUNCTION_VENDOR_INTERFACE:		req_type = USB_TYPE_VENDOR | USB_RECIP_INTERFACE;		break;	case URB_FUNCTION_VENDOR_ENDPOINT:		req_type = USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;		break;	case URB_FUNCTION_VENDOR_OTHER:		req_type = USB_TYPE_VENDOR | USB_RECIP_OTHER;		break;	case URB_FUNCTION_CLASS_DEVICE:		req_type = USB_TYPE_CLASS | USB_RECIP_DEVICE;		break;	case URB_FUNCTION_CLASS_INTERFACE:		req_type = USB_TYPE_CLASS | USB_RECIP_INTERFACE;		break;	case URB_FUNCTION_CLASS_ENDPOINT:		req_type = USB_TYPE_CLASS | USB_RECIP_ENDPOINT;		break;	case URB_FUNCTION_CLASS_OTHER:		req_type = USB_TYPE_CLASS | USB_RECIP_OTHER;		break;	default:		ERROR("unknown request type: %x", nt_urb->header.function);		req_type = 0;		break;	}	req_type |= vc_req->reserved_bits;	USBTRACE("req type: %08x", req_type);	if (vc_req->transfer_flags & USBD_TRANSFER_DIRECTION_IN) {		pipe = usb_rcvctrlpipe(udev, 0);		req_type |= USB_DIR_IN;		USBTRACE("pipe: %x, dir in", pipe);	} else {		pipe = usb_sndctrlpipe(udev, 0);		req_type |= USB_DIR_OUT;		USBTRACE("pipe: %x, dir out", pipe);	}	urb = wrap_alloc_urb(irp, pipe, vc_req->transfer_buffer,			     vc_req->transfer_buffer_length);	if (!urb) {		ERROR("couldn't allocate urb");		return USBD_STATUS_NO_MEMORY;	}	if (usb_pipein(pipe) &&	    (!(vc_req->transfer_flags & USBD_SHORT_TRANSFER_OK))) {		USBTRACE("short not ok");		urb->transfer_flags |= URB_SHORT_NOT_OK;	}	dr = kzalloc(sizeof(*dr), GFP_ATOMIC);	if (!dr) {		ERROR("couldn't allocate memory");		wrap_free_urb(urb);		return USBD_STATUS_NO_MEMORY;	}	dr->bRequestType = req_type;	dr->bRequest = vc_req->request;	dr->wValue = cpu_to_le16(vc_req->value);	dr->wIndex = cpu_to_le16((u16)vc_req->index);	dr->wLength = cpu_to_le16((u16)urb->transfer_buffer_length);	usb_fill_control_urb(urb, udev, pipe, (unsigned char *)dr,			     urb->transfer_buffer, urb->transfer_buffer_length,			     wrap_urb_complete, urb->context);	status = wrap_submit_urb(irp);	USBTRACE("status: %08X", status);	USBEXIT(return status);}static USBD_STATUS wrap_reset_pipe(struct usb_device *udev, struct irp *irp){	int ret;	union nt_urb *nt_urb;	usbd_pipe_handle pipe_handle;	unsigned int pipe1, pipe2;	nt_urb = IRP_URB(irp);	pipe_handle = nt_urb->pipe_req.pipe_handle;	/* TODO: not clear if both directions should be cleared? */	if (USBD_IS_BULK_PIPE(pipe_handle)) {		pipe1 = usb_rcvbulkpipe(udev, pipe_handle->bEndpointAddress);		pipe2 = usb_sndbulkpipe(udev, pipe_handle->bEndpointAddress);	} else if (USBD_IS_INT_PIPE(pipe_handle)) {		pipe1 = usb_rcvintpipe(udev, pipe_handle->bEndpointAddress);		pipe2 = pipe1;	} else {		WARNING("invalid pipe %d", pipe_handle->bEndpointAddress);		return USBD_STATUS_INVALID_PIPE_HANDLE;	}	USBTRACE("ep: %d, pipe: 0x%x", pipe_handle->bEndpointAddress, pipe1);	ret = usb_clear_halt(udev, pipe1);	if (ret)		USBTRACE("resetting pipe %d failed: %d", pipe1, ret);	if (pipe2 != pipe1) {		ret = usb_clear_halt(udev, pipe2);		if (ret)			USBTRACE("resetting pipe %d failed: %d", pipe2, ret);	}//	return wrap_urb_status(ret);	return USBD_STATUS_SUCCESS;}static USBD_STATUS wrap_abort_pipe(struct usb_device *udev, struct irp *irp){	union nt_urb *nt_urb;	usbd_pipe_handle pipe_handle;	struct wrap_urb *wrap_urb;	struct wrap_device *wd;	KIRQL irql;	wd = IRP_WRAP_DEVICE(irp);	nt_urb = IRP_URB(irp);	pipe_handle = nt_urb->pipe_req.pipe_handle;	USBENTER("%p, %x", irp, pipe_handle->bEndpointAddress);	IoAcquireCancelSpinLock(&irql);	nt_list_for_each_entry(wrap_urb, &wd->usb.wrap_urb_list, list) {		USBTRACE("%p, %p, %d, %x, %x", wrap_urb, wrap_urb->urb,			 wrap_urb->state, wrap_urb->urb->pipe,			 usb_pipeendpoint(wrap_urb->urb->pipe));		/* for WG111T driver, urbs for endpoint 0 should also		 * be canceled */		if ((usb_pipeendpoint(wrap_urb->urb->pipe) ==		     pipe_handle->bEndpointAddress) ||		    (usb_pipeendpoint(wrap_urb->urb->pipe) == 0)) {			if (wrap_cancel_urb(wrap_urb) == 0)				USBTRACE("canceled wrap_urb: %p", wrap_urb);		}	}	IoReleaseCancelSpinLock(irql);	NT_URB_STATUS(nt_urb) = USBD_STATUS_CANCELED;	USBEXIT(return USBD_STATUS_SUCCESS);}static USBD_STATUS wrap_set_clear_feature(struct usb_device *udev,					  struct irp *irp){	union nt_urb *nt_urb;	struct urb_control_feature_request *feat_req;	int ret = 0;	__u8 request, type;	__u16 feature;	nt_urb = IRP_URB(irp);	feat_req = &nt_urb->feat_req;	feature = feat_req->feature_selector;	switch (nt_urb->header.function) {	case URB_FUNCTION_SET_FEATURE_TO_DEVICE:		request = USB_REQ_SET_FEATURE;		type = USB_DT_DEVICE;		break;	case URB_FUNCTION_SET_FEATURE_TO_INTERFACE:		request = USB_REQ_SET_FEATURE;		type =  USB_DT_INTERFACE;		break;	case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT:		request = USB_REQ_SET_FEATURE;		type =  USB_DT_ENDPOINT;		break;	case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE:		request = USB_REQ_CLEAR_FEATURE;		type =  USB_DT_DEVICE;		break;	case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE:		request = USB_REQ_CLEAR_FEATURE;		type =  USB_DT_INTERFACE;		break;	case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT:		request = USB_REQ_CLEAR_FEATURE;		type =  USB_DT_ENDPOINT;		break;	default:		WARNING("invalid function: %x", nt_urb->header.function);		NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED;		return NT_URB_STATUS(nt_urb);	}	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, type,			      feature, feat_req->index, NULL, 0, 1000);	NT_URB_STATUS(nt_urb) = wrap_urb_status(ret);	USBEXIT(return NT_URB_STATUS(nt_urb));}static USBD_STATUS wrap_get_status_request(struct usb_device *udev,					   struct irp *irp){	union nt_urb *nt_urb;	struct urb_control_get_status_request *status_req;	int ret = 0;	__u8 type;	nt_urb = IRP_URB(irp);	status_req = &nt_urb->status_req;	switch (nt_urb->header.function) {	case URB_FUNCTION_GET_STATUS_FROM_DEVICE:		type = USB_RECIP_DEVICE;		break;	case URB_FUNCTION_GET_STATUS_FROM_INTERFACE:		type = USB_RECIP_INTERFACE;		break;	case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT:		type = USB_RECIP_ENDPOINT;		break;	default:		WARNING("invalid function: %x", nt_urb->header.function);		NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED;		return NT_URB_STATUS(nt_urb);	}	assert(status_req->transfer_buffer_length == sizeof(u16));	ret = usb_get_status(udev, type, status_req->index,			     status_req->transfer_buffer);	if (ret >= 0) {		assert(ret <= status_req->transfer_buffer_length);		status_req->transfer_buffer_length = ret;		NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS;	} else		NT_URB_STATUS(nt_urb) = wrap_urb_status(ret);	USBEXIT(return NT_URB_STATUS(nt_urb));}static void set_intf_pipe_info(struct wrap_device *wd,			       struct usb_interface *usb_intf,			       struct usbd_interface_information *intf){	int i;	struct usb_endpoint_descriptor *ep;	struct usbd_pipe_information *pipe;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)	for (i = 0; i < CUR_ALT_SETTING(usb_intf)->desc.bNumEndpoints; i++) {		ep = &(CUR_ALT_SETTING(usb_intf)->endpoint[i]).desc;#else	for (i = 0; i < CUR_ALT_SETTING(usb_intf).bNumEndpoints; i++) {		ep = &((CUR_ALT_SETTING(usb_intf)).endpoint[i]);#endif		if (i >= intf->bNumEndpoints) {			ERROR("intf %p has only %d endpoints, "			      "ignoring endpoints above %d",			      intf, intf->bNumEndpoints, i);			break;		}		pipe = &intf->pipes[i];		if (pipe->flags & USBD_PF_CHANGE_MAX_PACKET)			USBTRACE("pkt_sz: %d: %d", pipe->wMaxPacketSize,				 pipe->max_tx_size);		USBTRACE("driver wants max_tx_size to %d",			 pipe->max_tx_size);		pipe->wMaxPacketSize = ep->wMaxPacketSize;		pipe->bEndpointAddress = ep->bEndpointAddress;		pipe->type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;		if (pipe->type == UsbdPipeTypeInterrupt) {			/* Windows and Linux differ in how the			 * bInterval is interpretted */			/* for low speed:			   interval (Windows) -> frames per ms (Linux)			   0 to 15    -> 8			   16 to 35   -> 16			   36 to 255  -> 32			   for full speed: interval -> frames per ms			   1          -> 1			   2 to 3     -> 2			   4 to 7     -> 4			   8 to 15    -> 8			   16 to 31   -> 16			   32 to 255  -> 32			   for high speed: interval -> microframes			   1          -> 1			   2          -> 2			   3          -> 4			   4          -> 8			   5          -> 16			   6          -> 32			   7 to 255   -> 32			*/			if (wd->usb.udev->speed == USB_SPEED_LOW)				pipe->bInterval = ep->bInterval + 5;			else if (wd->usb.udev->speed == USB_SPEED_FULL)				pipe->bInterval = ep->bInterval;			else {				int i, j;				for (i = j = 1; j < ep->bInterval; i++)					j *= 2;				pipe->bInterval = i;			}		}		pipe->handle = ep;		USBTRACE("%d: ep 0x%x, type %d, pkt_sz %d, intv %d (%d),"			 "type: %d, handle %p", i, ep->bEndpointAddress,			 ep->bmAttributes, ep->wMaxPacketSize, ep->bInterval,			 pipe->bInterval, pipe->type, pipe->handle);	}}static USBD_STATUS wrap_select_configuration(struct wrap_device *wd,					     union nt_urb *nt_urb,					     struct irp *irp){	int i, ret;	struct usbd_select_configuration *sel_conf;	struct usb_device *udev;	struct usbd_interface_information *intf;	struct usb_config_descriptor *config;	struct usb_interface *usb_intf;	udev = wd->usb.udev;	sel_conf = &nt_urb->select_conf;	config = sel_conf->config;	USBTRACE("%p", config);	if (config == NULL) {		kill_all_urbs(wd, 1);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)		ret = usb_reset_configuration(udev);#else		ret = 0;#endif		return wrap_urb_status(ret);	}	USBTRACE("conf: %d, type: %d, length: %d, numif: %d, attr: %08x",		 config->bConfigurationValue, config->bDescriptorType,		 config->wTotalLength, config->bNumInterfaces,		 config->bmAttributes);	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),			      USB_REQ_SET_CONFIGURATION, 0,			      config->bConfigurationValue, 0,			      NULL, 0, USB_CTRL_SET_TIMEOUT);	if (ret < 0) {		ERROR("ret: %d", ret);		return wrap_urb_status(ret);	}	sel_conf->handle = udev->actconfig;	intf = &sel_conf->intf;	for (i = 0; i < config->bNumInterfaces && intf->bLength > 0;	     i++, intf = (((void *)intf) + intf->bLength)) {		USBTRACE("intf: %d, alt setting: %d",			 intf->bInterfaceNumber, intf->bAlternateSetting);		ret = usb_set_interface(udev, intf->bInterfaceNumber,					intf->bAlternateSetting);		if (ret < 0) {			ERROR("failed with %d", ret);			return wrap_urb_status(ret);		}		usb_intf = usb_ifnum_to_if(udev, intf->bInterfaceNumber);		if (!usb_intf) {			ERROR("couldn't obtain ifnum");			return USBD_STATUS_REQUEST_FAILED;		}		USBTRACE("intf: %p, num ep: %d", intf, intf->bNumEndpoints);		set_intf_pipe_info(wd, usb_intf, intf);	}	return USBD_STATUS_SUCCESS;}static USBD_STATUS wrap_select_interface(struct wrap_device *wd,					 union nt_urb *nt_urb,					 struct irp *irp){	int ret;	struct usbd_select_interface *sel_intf;	struct usb_device *udev;	struct usbd_interface_information *intf;	struct usb_interface *usb_intf;	udev = wd->usb.udev;	sel_intf = &nt_urb->select_intf;	intf = &sel_intf->intf;	ret = usb_set_interface(udev, intf->bInterfaceNumber,				intf->bAlternateSetting);	if (ret < 0) {		ERROR("failed with %d", ret);		return wrap_urb_status(ret);	}	usb_intf = usb_ifnum_to_if(udev, intf->bInterfaceNumber);	if (!usb_intf) {		ERROR("couldn't get interface information");		return USBD_STATUS_REQUEST_FAILED;	}	USBTRACE("intf: %p, num ep: %d", usb_intf, intf->bNumEndpoints);	set_intf_pipe_info(wd, usb_intf, intf);	return USBD_STATUS_SUCCESS;}static int wrap_usb_get_string(struct usb_device *udev, unsigned short langid,			       unsigned char index, void *buf, int size){	int i, ret;	/* if langid is 0, return array of langauges supported in	 * buf */	for (i = 0; i < 3; i++) {		ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),				      USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -