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

📄 usb.c

📁 ndis在linux下的无线网卡驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (control_desc->desc_type == USB_DT_STRING) {		USBTRACE("langid: %x", control_desc->language_id);		ret = wrap_usb_get_string(udev, control_desc->language_id,					  control_desc->index,					  control_desc->transfer_buffer,					  control_desc->transfer_buffer_length);	} else {		ret = usb_get_descriptor(udev, control_desc->desc_type,					 control_desc->index,					 control_desc->transfer_buffer,					 control_desc->transfer_buffer_length);	}	if (ret < 0) {		USBTRACE("request %d failed: %d", control_desc->desc_type, ret);		control_desc->transfer_buffer_length = 0;		return wrap_urb_status(ret);	} else {		USBTRACE("ret: %08x", ret);		control_desc->transfer_buffer_length = ret;		irp->io_status.info = ret;		return USBD_STATUS_SUCCESS;	}}static USBD_STATUS wrap_process_nt_urb(struct irp *irp){	union nt_urb *nt_urb;	struct usb_device *udev;	USBD_STATUS status;	struct wrap_device *wd;	wd = IRP_WRAP_DEVICE(irp);	udev = wd->usb.udev;	nt_urb = IRP_URB(irp);	USBENTER("nt_urb = %p, irp = %p, length = %d, function = %x",		 nt_urb, irp, nt_urb->header.length, nt_urb->header.function);	DUMP_IRP(irp);	switch (nt_urb->header.function) {		/* bulk/int and vendor/class urbs are submitted to		 * Linux USB core; if the call is sucessful, urb's		 * completion worker will return IRP later */	case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:		USBTRACE("submitting bulk/int irp: %p", irp);		status = wrap_bulk_or_intr_trans(irp);		break;	case URB_FUNCTION_VENDOR_DEVICE:	case URB_FUNCTION_VENDOR_INTERFACE:	case URB_FUNCTION_VENDOR_ENDPOINT:	case URB_FUNCTION_VENDOR_OTHER:	case URB_FUNCTION_CLASS_DEVICE:	case URB_FUNCTION_CLASS_INTERFACE:	case URB_FUNCTION_CLASS_ENDPOINT:	case URB_FUNCTION_CLASS_OTHER:		USBTRACE("submitting vendor/class irp: %p", irp);		status = wrap_vendor_or_class_req(irp);		break;		/* rest are synchronous */	case URB_FUNCTION_SELECT_CONFIGURATION:		status = wrap_select_configuration(wd, nt_urb, irp);		NT_URB_STATUS(nt_urb) = status;		break;	case URB_FUNCTION_SELECT_INTERFACE:		status = wrap_select_interface(wd, nt_urb, irp);		NT_URB_STATUS(nt_urb) = status;		break;	case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:		status = wrap_get_descriptor(wd, nt_urb, irp);		NT_URB_STATUS(nt_urb) = status;		break;	case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:		status = wrap_reset_pipe(udev, irp);		NT_URB_STATUS(nt_urb) = status;		break;	case URB_FUNCTION_ABORT_PIPE:		status = wrap_abort_pipe(udev, irp);		break;	default:		ERROR("function %x not implemented", nt_urb->header.function);		status = NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED;		break;	}	USBTRACE("status: %08X", status);	return status;}static USBD_STATUS wrap_reset_port(struct irp *irp){	no_warn_unused int ret, lock = 0;	struct wrap_device *wd;	wd = IRP_WRAP_DEVICE(irp);	USBENTER("%p, %p", wd, wd->usb.udev);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)	lock = usb_lock_device_for_reset(wd->usb.udev, wd->usb.intf);	if (lock < 0) {		WARNING("locking failed: %d", lock);		return wrap_urb_status(lock);	}#endif	ret = usb_reset_device(wd->usb.udev);	if (ret < 0)		USBTRACE("reset failed: %d", ret);	/* TODO: should reconfigure? */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)	if (lock)		usb_unlock_device(wd->usb.udev);#endif	return wrap_urb_status(ret);}static USBD_STATUS wrap_get_port_status(struct irp *irp){	struct wrap_device *wd;	ULONG *status;	wd = IRP_WRAP_DEVICE(irp);	USBENTER("%p, %p", wd, wd->usb.udev);	status = IoGetCurrentIrpStackLocation(irp)->params.others.arg1;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)	{		enum usb_device_state state;		state = wd->usb.udev->state;		if (state != USB_STATE_NOTATTACHED &&		    state != USB_STATE_SUSPENDED) {			*status |= USBD_PORT_CONNECTED;			if (state == USB_STATE_CONFIGURED)				*status |= USBD_PORT_ENABLED;		}		USBTRACE("state: %d, *status: %08X", state, *status);	}#else	/* TODO: how to get current status? */	*status = USBD_PORT_CONNECTED | USBD_PORT_ENABLED;#endif	return USBD_STATUS_SUCCESS;}NTSTATUS wrap_submit_irp(struct device_object *pdo, struct irp *irp){	struct io_stack_location *irp_sl;	struct wrap_device *wd;	USBD_STATUS status;	struct usbd_idle_callback *idle_callback;	USBTRACE("%p, %p", pdo, irp);	wd = pdo->reserved;//	if (wd->usb.intf == NULL)//		USBEXIT(return STATUS_DEVICE_REMOVED);	IRP_WRAP_DEVICE(irp) = wd;	irp_sl = IoGetCurrentIrpStackLocation(irp);	switch (irp_sl->params.dev_ioctl.code) {	case IOCTL_INTERNAL_USB_SUBMIT_URB:		status = wrap_process_nt_urb(irp);		break;	case IOCTL_INTERNAL_USB_RESET_PORT:		status = wrap_reset_port(irp);		break;	case IOCTL_INTERNAL_USB_GET_PORT_STATUS:		status = wrap_get_port_status(irp);		break;	case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:		idle_callback = irp_sl->params.dev_ioctl.type3_input_buf;		USBTRACE("suspend function: %p", idle_callback->callback);		status = USBD_STATUS_NOT_SUPPORTED;		break;	default:		ERROR("ioctl %08X NOT IMPLEMENTED",		      irp_sl->params.dev_ioctl.code);		status = USBD_STATUS_NOT_SUPPORTED;		break;	}	USBTRACE("status: %08X", status);	if (status == USBD_STATUS_PENDING) {		/* don't touch this IRP - it may have been already		 * completed/returned */		return STATUS_PENDING;	} else {		irp->io_status.status = nt_urb_irp_status(status);		if (status != USBD_STATUS_SUCCESS)			irp->io_status.info = 0;		USBEXIT(return irp->io_status.status);	}}/* TODO: The example on msdn in reference section suggests that second * argument should be an array of usbd_interface_information, but * description and examples elsewhere suggest that it should be * usbd_interface_list_entry structre. Which is correct? */wstdcall union nt_urb *WIN_FUNC(USBD_CreateConfigurationRequestEx,2)	(struct usb_config_descriptor *config,	 struct usbd_interface_list_entry *intf_list){	int size, i, n;	struct usbd_interface_information *intf;	struct usbd_pipe_information *pipe;	struct usb_interface_descriptor *intf_desc;	struct usbd_select_configuration *select_conf;	USBENTER("config = %p, intf_list = %p", config, intf_list);	/* calculate size required; select_conf already has space for	 * one intf structure */	size = sizeof(*select_conf) - sizeof(*intf);	for (n = 0; n < config->bNumInterfaces; n++) {		i = intf_list[n].intf_desc->bNumEndpoints;		/* intf already has space for one pipe */		size += sizeof(*intf) + (i - 1) * sizeof(*pipe);	}	/* don't use kmalloc - driver frees it with ExFreePool */	select_conf = ExAllocatePoolWithTag(NonPagedPool, size,					    POOL_TAG('L', 'U', 'S', 'B'));	if (!select_conf) {		WARNING("couldn't allocate memory");		return NULL;	}	memset(select_conf, 0, size);	intf = &select_conf->intf;	select_conf->handle = config;	for (n = 0; n < config->bNumInterfaces && intf_list[n].intf_desc; n++) {		/* initialize 'intf' fields in intf_list so they point		 * to appropriate entry; these may be read/written by		 * driver after this function returns */		intf_list[n].intf = intf;		intf_desc = intf_list[n].intf_desc;		i = intf_desc->bNumEndpoints;		intf->bLength = sizeof(*intf) + (i - 1) * sizeof(*pipe);		intf->bInterfaceNumber = intf_desc->bInterfaceNumber;		intf->bAlternateSetting = intf_desc->bAlternateSetting;		intf->bInterfaceClass = intf_desc->bInterfaceClass;		intf->bInterfaceSubClass = intf_desc->bInterfaceSubClass;		intf->bInterfaceProtocol = intf_desc->bInterfaceProtocol;		intf->bNumEndpoints = intf_desc->bNumEndpoints;		pipe = &intf->pipes[0];		for (i = 0; i < intf->bNumEndpoints; i++) {			memset(&pipe[i], 0, sizeof(*pipe));			pipe[i].max_tx_size =				USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;		}		intf->handle = intf_desc;		intf = (((void *)intf) + intf->bLength);	}	select_conf->header.function = URB_FUNCTION_SELECT_CONFIGURATION;	select_conf->header.length = size;	select_conf->config = config;	USBEXIT(return (union nt_urb *)select_conf);}WIN_SYMBOL_MAP("_USBD_CreateConfigurationRequestEx@8", USBD_CreateConfigurationRequestEx)wstdcall struct usb_interface_descriptor *WIN_FUNC(USBD_ParseConfigurationDescriptorEx,7)	(struct usb_config_descriptor *config, void *start,	 LONG bInterfaceNumber, LONG bAlternateSetting, LONG bInterfaceClass,	 LONG bInterfaceSubClass, LONG bInterfaceProtocol){	void *pos;	struct usb_interface_descriptor *intf;	USBENTER("config = %p, start = %p, ifnum = %d, alt_setting = %d,"		 " class = %d, subclass = %d, proto = %d", config, start,		 bInterfaceNumber, bAlternateSetting, bInterfaceClass,		 bInterfaceSubClass, bInterfaceProtocol);	for (pos = start; pos < ((void *)config + config->wTotalLength);	     pos += intf->bLength) {		intf = pos;		if ((intf->bDescriptorType == USB_DT_INTERFACE) &&		    ((bInterfaceNumber == -1) ||		     (intf->bInterfaceNumber == bInterfaceNumber)) &&		    ((bAlternateSetting == -1) ||		     (intf->bAlternateSetting == bAlternateSetting)) &&		    ((bInterfaceClass == -1) ||		     (intf->bInterfaceClass == bInterfaceClass)) &&		    ((bInterfaceSubClass == -1) ||		     (intf->bInterfaceSubClass == bInterfaceSubClass)) &&		    ((bInterfaceProtocol == -1) ||		     (intf->bInterfaceProtocol == bInterfaceProtocol))) {			USBTRACE("selected interface = %p", intf);			USBEXIT(return intf);		}	}	USBEXIT(return NULL);}WIN_SYMBOL_MAP("_USBD_ParseConfigurationDescriptorEx@28", USBD_ParseConfigurationDescriptorEx)wstdcall union nt_urb *WIN_FUNC(USBD_CreateConfigurationRequest,2)	(struct usb_config_descriptor *config, USHORT *size){	union nt_urb *nt_urb;	struct usbd_interface_list_entry intf_list[2];	struct usb_interface_descriptor *intf_desc;	USBENTER("config = %p, urb_size = %p", config, size);	intf_desc = USBD_ParseConfigurationDescriptorEx(config, config, -1, -1,							-1, -1, -1);	intf_list[0].intf_desc = intf_desc;	intf_list[0].intf = NULL;	intf_list[1].intf_desc = NULL;	intf_list[1].intf = NULL;	nt_urb = USBD_CreateConfigurationRequestEx(config, intf_list);	if (!nt_urb)		return NULL;	*size = nt_urb->select_conf.header.length;	USBEXIT(return nt_urb);}wstdcall struct usb_interface_descriptor *WIN_FUNC(USBD_ParseConfigurationDescriptor,3)	(struct usb_config_descriptor *config, UCHAR bInterfaceNumber,	 UCHAR bAlternateSetting){	return USBD_ParseConfigurationDescriptorEx(config, config,						   bInterfaceNumber,						   bAlternateSetting,						   -1, -1, -1);}wstdcall usb_common_descriptor_t *WIN_FUNC(USBD_ParseDescriptors,4)	(void *buf, ULONG length, void *start, LONG type){	usb_common_descriptor_t *descr = start;	while ((void *)descr < buf + length) {		if (descr->bDescriptorType == type)			return descr;		if (descr->bLength == 0)			break;		descr = (void *)descr + descr->bLength;	}	USBEXIT(return NULL);}WIN_SYMBOL_MAP("_USBD_ParseDescriptors@16", USBD_ParseDescriptors)wstdcall void WIN_FUNC(USBD_GetUSBDIVersion,1)	(struct usbd_version_info *version_info){	/* this function is obsolete in Windows XP */	if (version_info) {		version_info->usbdi_version = USBDI_VERSION_XP;		/* TODO: how do we get this correctly? */		version_info->supported_usb_version = 0x110;	}	USBEXIT(return);}wstdcall voidUSBD_InterfaceGetUSBDIVersion(void *context,			      struct usbd_version_info *version_info,			      ULONG *hcd_capa){	struct wrap_device *wd = context;	if (version_info) {		version_info->usbdi_version = USBDI_VERSION_XP;		if (wd->usb.udev->speed == USB_SPEED_HIGH)			version_info->supported_usb_version = 0x200;		else			version_info->supported_usb_version = 0x110;	}	*hcd_capa = USB_HCD_CAPS_SUPPORTS_RT_THREADS;	USBEXIT(return);}wstdcall BOOLEAN USBD_InterfaceIsDeviceHighSpeed(void *context){	struct wrap_device *wd = context;	USBTRACE("wd: %p", wd);	if (wd->usb.udev->speed == USB_SPEED_HIGH)		USBEXIT(return TRUE);	else		USBEXIT(return FALSE);}wstdcall void USBD_InterfaceReference(void *context){	USBTRACE("%p", context);	TODO();}wstdcall void USBD_InterfaceDereference(void *context){	USBTRACE("%p", context);	TODO();}wstdcall NTSTATUS USBD_InterfaceQueryBusTime(void *context, ULONG *frame){	struct wrap_device *wd = context;	*frame = usb_get_current_frame_number(wd->usb.udev);	USBEXIT(return STATUS_SUCCESS);}wstdcall NTSTATUS USBD_InterfaceSubmitIsoOutUrb(void *context,					       union nt_urb *nt_urb){	/* TODO: implement this */	TODO();	USBEXIT(return STATUS_NOT_IMPLEMENTED);}wstdcall NTSTATUSUSBD_InterfaceQueryBusInformation(void *context, ULONG level, void *buf,				  ULONG *buf_length, ULONG *buf_actual_length){	struct wrap_device *wd = context;	struct usb_bus_information_level *bus_info;	struct usb_bus *bus;	bus = wd->usb.udev->bus;	bus_info = buf;	TODO();	USBEXIT(return STATUS_NOT_IMPLEMENTED);}wstdcall NTSTATUSUSBD_InterfaceLogEntry(void *context, ULONG driver_tag, ULONG enum_tag,		       ULONG p1, ULONG p2){	ERROR("%p, %x, %x, %x, %x", context, driver_tag, enum_tag, p1, p2);	USBEXIT(return STATUS_SUCCESS);}#include "usb_exports.h"int usb_init(void){	InitializeListHead(&wrap_urb_complete_list);	nt_spin_lock_init(&wrap_urb_complete_list_lock);#ifdef USB_TASKLET	tasklet_init(&wrap_urb_complete_work, wrap_urb_complete_worker, 0);#else	initialize_work(&wrap_urb_complete_work, wrap_urb_complete_worker, NULL);#endif#ifdef USB_DEBUG	urb_id = 0;#endif	return 0;}void usb_exit(void){#ifdef USB_TASKLET	tasklet_kill(&wrap_urb_complete_work);#endif	USBEXIT(return);}int usb_init_device(struct wrap_device *wd){	InitializeListHead(&wd->usb.wrap_urb_list);	wd->usb.num_alloc_urbs = 0;	USBEXIT(return 0);}void usb_exit_device(struct wrap_device *wd){	kill_all_urbs(wd, 0);	USBEXIT(return);}

⌨️ 快捷键说明

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