Linux下的USB转SATA学习

USB层转SCSI层

  1. kernel/drivers/usb/storage/uas.c

使用usb 的设备添加一个scsi设备
流程:module_usb_driver(uas_driver);
|
module_driver(__usb_driver, usb_register, usb_deregister)
|
usb_register(driver)
|
usb_register_driver(driver, …)
|
driver_register

	  /**
 * usb_register_device_driver - register a USB device (not interface) driver
 * @new_udriver: USB operations for the device driver
 * @owner: module owner of this driver.
 *
 * Registers a USB device driver with the USB core.  The list of
 * unattached devices will be rescanned whenever a new driver is
 * added, allowing the new driver to attach to any recognized devices.
 *
 * Return: A negative error code on failure and 0 on success.
 */
int usb_register_device_driver(struct usb_device_driver *new_udriver,
		struct module *owner)
{
	int retval = 0;

	if (usb_disabled())
		return -ENODEV;

	new_udriver->drvwrap.for_devices = 1;
	new_udriver->drvwrap.driver.name = new_udriver->name;
	new_udriver->drvwrap.driver.bus = &usb_bus_type;
	new_udriver->drvwrap.driver.probe = usb_probe_device;
	new_udriver->drvwrap.driver.remove = usb_unbind_device;
	new_udriver->drvwrap.driver.owner = owner;

	retval = driver_register(&new_udriver->drvwrap.driver);

	if (!retval)
		pr_info("%s: registered new device driver %s\n",
			usbcore_name, new_udriver->name);
	else
		printk(KERN_ERR "%s: error %d registering device "
			"	driver %s\n",
			usbcore_name, retval, new_udriver->name);

	return retval;
}
EXPORT_SYMBOL_GPL(usb_register_device_driver);

usb_bus_type定义
struct bus_type usb_bus_type = {
	.name =		"usb",
	.match =	usb_device_match,
	.uevent =	usb_uevent,
};

static int usb_device_match(struct device *dev, struct device_driver *drv)
{
	/* devices and interfaces are handled separately */
	if (is_usb_device(dev)) {

		/* interface drivers never match devices */
		if (!is_usb_device_driver(drv))
			return 0;

		/* TODO: Add real matching code */
		return 1;

	} else if (is_usb_interface(dev)) {
		struct usb_interface *intf;
		struct usb_driver *usb_drv;
		const struct usb_device_id *id;

		/* device drivers never match interfaces */
		if (is_usb_device_driver(drv))
			return 0;

		intf = to_usb_interface(dev);
		usb_drv = to_usb_driver(drv);

		id = usb_match_id(intf, usb_drv->id_table);
		if (id)
			return 1;
	id = usb_match_dynamic_id(intf, usb_drv);
	if (id)
		return 1;
}

	return 0;
}



const struct usb_device_id *usb_match_id(struct usb_interface *interface,
					 const struct usb_device_id *id)
{
	/* proc_connectinfo in devio.c may call us with id == NULL. */
	if (id == NULL)
		return NULL;

	/* It is important to check that id->driver_info is nonzero,
	   since an entry that is all zeroes except for a nonzero
	   id->driver_info is the way to create an entry that
	   indicates that the driver want to examine every
	   device and interface. */
	for (; id->idVendor || id->idProduct || id->bDeviceClass ||
	       id->bInterfaceClass || id->driver_info; id++) {
		if (usb_match_one_id(interface, id))
			return id;
	}

	return NULL;
}


/* returns 0 if no match, 1 if match */
int usb_match_one_id(struct usb_interface *interface,
		     const struct usb_device_id *id)
{
	struct usb_host_interface *intf;
	struct usb_device *dev;

	/* proc_connectinfo in devio.c may call us with id == NULL. */
	if (id == NULL)
		return 0;

	intf = interface->cur_altsetting;
	dev = interface_to_usbdev(interface);

	if (!usb_match_device(dev, id))
		return 0;

	return usb_match_one_id_intf(dev, intf, id);
}

/* returns 0 if no match, 1 if match */
int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
{
	if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
	    id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
		return 0;

if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
    id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
	return 0;

/* No need to test id->bcdDevice_lo != 0, since 0 is never
   greater than any unsigned number. */
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
    (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
	return 0;

if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
    (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
	return 0;

if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
   

 (id->bDeviceClass != dev->descriptor.bDeviceClass))
		return 0;

	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
	    (id->bDeviceSubClass != dev->descriptor.bDeviceSubClass))
		return 0;

	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
	    (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
		return 0;

	return 1;
}

SCSI层转SATA层

  1. kernel/drivers/scsi/libsas/sas_ata.c

scsi与sata的转换,直接操作sata硬盘

SATA驱动的具体实现

  1. kernel/drivers/ata/

该目录下是一些sata驱动的具体实现

  1. (SATA转USB控制器芯片)ASM1053E ASM1153E对比

https://blog.csdn.net/jiangbeicaizi000/article/details/81983874
Linux下的USB转SATA学习_第1张图片

你可能感兴趣的:(usb)