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

📄 message.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
		case 0:			cpu_relax ();			break;			/* fail any uncompleted urbs */		default:			io->urbs [i]->dev = NULL;			io->urbs [i]->status = retval;			dev_dbg (&io->dev->dev, "%s, submit --> %d\n",				__FUNCTION__, retval);			usb_sg_cancel (io);		}		spin_lock_irq (&io->lock);		if (retval && (io->status == 0 || io->status == -ECONNRESET))			io->status = retval;	}	io->count -= entries - i;	if (io->count == 0)		complete (&io->complete);	spin_unlock_irq (&io->lock);	/* OK, yes, this could be packaged as non-blocking.	 * So could the submit loop above ... but it's easier to	 * solve neither problem than to solve both!	 */	wait_for_completion (&io->complete);	sg_clean (io);}/** * usb_sg_cancel - stop scatter/gather i/o issued by usb_sg_wait() * @io: request block, initialized with usb_sg_init() * * This stops a request after it has been started by usb_sg_wait(). * It can also prevents one initialized by usb_sg_init() from starting, * so that call just frees resources allocated to the request. */void usb_sg_cancel (struct usb_sg_request *io){	unsigned long	flags;	spin_lock_irqsave (&io->lock, flags);	/* shut everything down, if it didn't already */	if (!io->status) {		int	i;		io->status = -ECONNRESET;		spin_unlock (&io->lock);		for (i = 0; i < io->entries; i++) {			int	retval;			if (!io->urbs [i]->dev)				continue;			retval = usb_unlink_urb (io->urbs [i]);			if (retval != -EINPROGRESS && retval != -EBUSY)				dev_warn (&io->dev->dev, "%s, unlink --> %d\n",					__FUNCTION__, retval);		}		spin_lock (&io->lock);	}	spin_unlock_irqrestore (&io->lock, flags);}/*-------------------------------------------------------------------*//** * usb_get_descriptor - issues a generic GET_DESCRIPTOR request * @dev: the device whose descriptor is being retrieved * @type: the descriptor type (USB_DT_*) * @index: the number of the descriptor * @buf: where to put the descriptor * @size: how big is "buf"? * Context: !in_interrupt () * * Gets a USB descriptor.  Convenience functions exist to simplify * getting some types of descriptors.  Use * usb_get_string() or usb_string() for USB_DT_STRING. * Device (USB_DT_DEVICE) and configuration descriptors (USB_DT_CONFIG) * are part of the device structure. * In addition to a number of USB-standard descriptors, some * devices also use class-specific or vendor-specific descriptors. * * This call is synchronous, and may not be used in an interrupt context. * * Returns the number of bytes received on success, or else the status code * returned by the underlying usb_control_msg() call. */int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size){	int i;	int result;		memset(buf,0,size);	// Make sure we parse really received data	for (i = 0; i < 3; ++i) {		/* retry on length 0 or stall; some devices are flakey */		result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),				USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,				(type << 8) + index, 0, buf, size,				HZ * USB_CTRL_GET_TIMEOUT);		if (result == 0 || result == -EPIPE)			continue;		if (result > 1 && ((u8 *)buf)[1] != type) {			result = -EPROTO;			continue;		}		break;	}	return result;}/** * usb_get_string - gets a string descriptor * @dev: the device whose string descriptor is being retrieved * @langid: code for language chosen (from string descriptor zero) * @index: the number of the descriptor * @buf: where to put the string * @size: how big is "buf"? * Context: !in_interrupt () * * Retrieves a string, encoded using UTF-16LE (Unicode, 16 bits per character, * in little-endian byte order). * The usb_string() function will often be a convenient way to turn * these strings into kernel-printable form. * * Strings may be referenced in device, configuration, interface, or other * descriptors, and could also be used in vendor-specific ways. * * This call is synchronous, and may not be used in an interrupt context. * * Returns the number of bytes received on success, or else the status code * returned by the underlying usb_control_msg() call. */int usb_get_string(struct usb_device *dev, unsigned short langid,		unsigned char index, void *buf, int size){	int i;	int result;	for (i = 0; i < 3; ++i) {		/* retry on length 0 or stall; some devices are flakey */		result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),			USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,			(USB_DT_STRING << 8) + index, langid, buf, size,			HZ * USB_CTRL_GET_TIMEOUT);		if (!(result == 0 || result == -EPIPE))			break;	}	return result;}static void usb_try_string_workarounds(unsigned char *buf, int *length){	int newlength, oldlength = *length;	for (newlength = 2; newlength + 1 < oldlength; newlength += 2)		if (!isprint(buf[newlength]) || buf[newlength + 1])			break;	if (newlength > 2) {		buf[0] = newlength;		*length = newlength;	}}static int usb_string_sub(struct usb_device *dev, unsigned int langid,		unsigned int index, unsigned char *buf){	int rc;	/* Try to read the string descriptor by asking for the maximum	 * possible number of bytes */	rc = usb_get_string(dev, langid, index, buf, 255);	/* If that failed try to read the descriptor length, then	 * ask for just that many bytes */	if (rc < 2) {		rc = usb_get_string(dev, langid, index, buf, 2);		if (rc == 2)			rc = usb_get_string(dev, langid, index, buf, buf[0]);	}	if (rc >= 2) {		if (!buf[0] && !buf[1])			usb_try_string_workarounds(buf, &rc);		/* There might be extra junk at the end of the descriptor */		if (buf[0] < rc)			rc = buf[0];		rc = rc - (rc & 1); /* force a multiple of two */	}	if (rc < 2)		rc = (rc < 0 ? rc : -EINVAL);	return rc;}/** * usb_string - returns ISO 8859-1 version of a string descriptor * @dev: the device whose string descriptor is being retrieved * @index: the number of the descriptor * @buf: where to put the string * @size: how big is "buf"? * Context: !in_interrupt () *  * This converts the UTF-16LE encoded strings returned by devices, from * usb_get_string_descriptor(), to null-terminated ISO-8859-1 encoded ones * that are more usable in most kernel contexts.  Note that all characters * in the chosen descriptor that can't be encoded using ISO-8859-1 * are converted to the question mark ("?") character, and this function * chooses strings in the first language supported by the device. * * The ASCII (or, redundantly, "US-ASCII") character set is the seven-bit * subset of ISO 8859-1. ISO-8859-1 is the eight-bit subset of Unicode, * and is appropriate for use many uses of English and several other * Western European languages.  (But it doesn't include the "Euro" symbol.) * * This call is synchronous, and may not be used in an interrupt context. * * Returns length of the string (>= 0) or usb_control_msg status (< 0). */int usb_string(struct usb_device *dev, int index, char *buf, size_t size){	unsigned char *tbuf;	int err;	unsigned int u, idx;	if (dev->state == USB_STATE_SUSPENDED)		return -EHOSTUNREACH;	if (size <= 0 || !buf || !index)		return -EINVAL;	buf[0] = 0;	tbuf = kmalloc(256, GFP_KERNEL);	if (!tbuf)		return -ENOMEM;	/* get langid for strings if it's not yet known */	if (!dev->have_langid) {		err = usb_string_sub(dev, 0, 0, tbuf);		if (err < 0) {			dev_err (&dev->dev,				"string descriptor 0 read error: %d\n",				err);			goto errout;		} else if (err < 4) {			dev_err (&dev->dev, "string descriptor 0 too short\n");			err = -EINVAL;			goto errout;		} else {			dev->have_langid = -1;			dev->string_langid = tbuf[2] | (tbuf[3]<< 8);				/* always use the first langid listed */			dev_dbg (&dev->dev, "default language 0x%04x\n",				dev->string_langid);		}	}		err = usb_string_sub(dev, dev->string_langid, index, tbuf);	if (err < 0)		goto errout;	size--;		/* leave room for trailing NULL char in output buffer */	for (idx = 0, u = 2; u < err; u += 2) {		if (idx >= size)			break;		if (tbuf[u+1])			/* high byte */			buf[idx++] = '?';  /* non ISO-8859-1 character */		else			buf[idx++] = tbuf[u];	}	buf[idx] = 0;	err = idx;	if (tbuf[1] != USB_DT_STRING)		dev_dbg(&dev->dev, "wrong descriptor type %02x for string %d (\"%s\")\n", tbuf[1], index, buf); errout:	kfree(tbuf);	return err;}/* * usb_get_device_descriptor - (re)reads the device descriptor (usbcore) * @dev: the device whose device descriptor is being updated * @size: how much of the descriptor to read * Context: !in_interrupt () * * Updates the copy of the device descriptor stored in the device structure, * which dedicates space for this purpose.  Note that several fields are * converted to the host CPU's byte order:  the USB version (bcdUSB), and * vendors product and version fields (idVendor, idProduct, and bcdDevice). * That lets device drivers compare against non-byteswapped constants. * * Not exported, only for use by the core.  If drivers really want to read * the device descriptor directly, they can call usb_get_descriptor() with * type = USB_DT_DEVICE and index = 0. * * This call is synchronous, and may not be used in an interrupt context. * * Returns the number of bytes received on success, or else the status code * returned by the underlying usb_control_msg() call. */int usb_get_device_descriptor(struct usb_device *dev, unsigned int size){	struct usb_device_descriptor *desc;	int ret;	if (size > sizeof(*desc))		return -EINVAL;	desc = kmalloc(sizeof(*desc), GFP_NOIO);	if (!desc)		return -ENOMEM;	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);	if (ret >= 0) 		memcpy(&dev->descriptor, desc, size);	kfree(desc);	return ret;}/** * usb_get_status - issues a GET_STATUS call * @dev: the device whose status is being checked * @type: USB_RECIP_*; for device, interface, or endpoint * @target: zero (for device), else interface or endpoint number * @data: pointer to two bytes of bitmap data * Context: !in_interrupt () * * Returns device, interface, or endpoint status.  Normally only of * interest to see if the device is self powered, or has enabled the * remote wakeup facility; or whether a bulk or interrupt endpoint * is halted ("stalled"). * * Bits in these status bitmaps are set using the SET_FEATURE request, * and cleared using the CLEAR_FEATURE request.  The usb_clear_halt() * function should be used to clear halt ("stall") status. * * This call is synchronous, and may not be used in an interrupt context. * * Returns the number of bytes received on success, or else the status code * returned by the underlying usb_control_msg() call. */int usb_get_status(struct usb_device *dev, int type, int target, void *data){	int ret;	u16 *status = kmalloc(sizeof(*status), GFP_KERNEL);	if (!status)		return -ENOMEM;	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),		USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, status,		sizeof(*status), HZ * USB_CTRL_GET_TIMEOUT);	*(u16 *)data = *status;	kfree(status);	return ret;}/** * usb_clear_halt - tells device to clear endpoint halt/stall condition * @dev: device whose endpoint is halted * @pipe: endpoint "pipe" being cleared * Context: !in_interrupt () * * This is used to clear halt conditions for bulk and interrupt endpoints, * as reported by URB completion status.  Endpoints that are halted are * sometimes referred to as being "stalled".  Such endpoints are unable * to transmit or receive data until the halt status is cleared.  Any URBs * queued for such an endpoint should normally be unlinked by the driver * before clearing the halt condition, as described in sections 5.7.5 * and 5.8.5 of the USB 2.0 spec. * * Note that control and isochronous endpoints don't halt, although control * endpoints report "protocol stall" (for unsupported requests) using the * same status code used to report a true stall. * * This call is synchronous, and may not be used in an interrupt context. * * Returns zero on success, or else the status code returned by the * underlying usb_control_msg() call. */int usb_clear_halt(struct usb_device *dev, int pipe){	int result;	int endp = usb_pipeendpoint(pipe);		if (usb_pipein (pipe))		endp |= USB_DIR_IN;	/* we don't care if it wasn't halted first. in fact some devices	 * (like some ibmcam model 1 units) seem to expect hosts to make	 * this request for iso endpoints, which can't halt!	 */	result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),		USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,		USB_ENDPOINT_HALT, endp, NULL, 0,		HZ * USB_CTRL_SET_TIMEOUT);	/* don't un-halt or force to DATA0 except on success */	if (result < 0)		return result;	/* NOTE:  seems like Microsoft and Apple don't bother verifying	 * the clear "took", so some devices could lock up if you check...	 * such as the Hagiwara FlashGate DUAL.  So we won't bother.	 *	 * NOTE:  make sure the logic here doesn't diverge much from	 * the copy in usb-storage, for as long as we need two copies.	 */	/* toggle was reset by the clear */	usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);	return 0;}/** * usb_disable_endpoint -- Disable an endpoint by address * @dev: the device whose endpoint is being disabled * @epaddr: the endpoint's address.  Endpoint number for output, *	endpoint number + USB_DIR_IN for input * * Deallocates hcd/hardware state for this endpoint ... and nukes all * pending urbs. * * If the HCD hasn't registered a disable() function, this sets the * endpoint's maxpacket size to 0 to prevent further submissions. */void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr){	unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;	struct usb_host_endpoint *ep;	if (!dev)		return;	if (usb_endpoint_out(epaddr)) {		ep = dev->ep_out[epnum];		dev->ep_out[epnum] = NULL;	} else {		ep = dev->ep_in[epnum];		dev->ep_in[epnum] = NULL;	}	if (ep && dev->bus && dev->bus->op && dev->bus->op->disable)		dev->bus->op->disable(dev, ep);}/** * usb_disable_interface -- Disable all endpoints for an interface * @dev: the device whose interface is being disabled * @intf: pointer to the interface descriptor * * Disables all the endpoints for the interface's current altsetting. */void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf){	struct usb_host_interface *alt = intf->cur_altsetting;	int i;	for (i = 0; i < alt->desc.bNumEndpoints; ++i) {		usb_disable_endpoint(dev,				alt->endpoint[i].desc.bEndpointAddress);	}}/* * usb_disable_device - Disable all the endpoints for a USB device * @dev: the device whose endpoints are being disabled * @skip_ep0: 0 to disable endpoint 0, 1 to skip it. * * Disables all the device's endpoints, potentially including endpoint 0. * Deallocates hcd/hardware state for the endpoints (nuking all or most * pending urbs) and usbcore state for the interfaces, so that usbcore * must usb_set_configuration() before any interfaces could be used. */

⌨️ 快捷键说明

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