USB Core 七

 

struct usb_hcd {

 /*
 * housekeeping
 */
 struct usb_bus self; /* hcd is-a bus */
 struct kref kref; /* reference counter */

 const char *product_desc; /* 主机控制器的产品描述字符串,对于UHCI,它为“UHCI Host Controller */
/*这里边儿保存的是“ehci-hcd:usb1”之类的字符串,也就是驱动的大名再加上总线编号。*/
 char irq_descr[24]; 


 struct timer_list rh_timer; /* drives root-hub polling */
 struct urb *status_urb; /* the current status urb */
 #ifdef CONFIG_PM
 struct work_struct wakeup_work; /* for remote wakeup */
 #endif

 /*
 * hardware info/state
 */
 const struct hc_driver *driver; /* hw-specific hooks */

 /* Flags that need to be manipulated atomically */
 unsigned long flags;
 #define HCD_FLAG_HW_ACCESSIBLE 0x00000001

 #define HCD_FLAG_SAW_IRQ 0x00000002

 unsigned rh_registered:1;/* is root hub registered? */

 /* The next flag is a stopgap, to be removed when all the HCDs
  * support the new root-hub polling mechanism. */
  unsigned uses_new_polling:1;
 unsigned poll_rh:1; /* poll for rh status? */
 unsigned poll_pending:1; /* status has changed? */
 unsigned wireless:1; /* Wireless USB HCD */
//wireless,是不是无线usb
 int irq; /* irq allocated */
 void __iomem *regs; /* device memory/io */
 u64 rsrc_start; /* memory/io resource start 是从表里读出来的host controller 的I/O 端口或内存的首地址*/
 u64 rsrc_len; /* memory/io resource length 从表里读出来的host controller 的I/O 端口或内存的长度*/
 unsigned power_budget; /* in mA, 0 = no limit 能够提供的电流*/

 #define HCD_BUFFER_POOLS 4  //表示每个主机控制器可以有4 个dma 池
 struct dma_pool *pool [HCD_BUFFER_POOLS];

 int state;
 # define __ACTIVE 0x01
 # define __SUSPEND 0x04
 # define __TRANSIENT 0x80

 # define HC_STATE_HALT 0
 # define HC_STATE_RUNNING (__ACTIVE)
 # define HC_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE)
 # define HC_STATE_RESUMING (__SUSPEND|__TRANSIENT)
 # define HC_STATE_SUSPENDED (__SUSPEND)

 #define HC_IS_RUNNING(state) ((state) & __ACTIVE)
 #define HC_IS_SUSPENDED(state) ((state) & __SUSPEND)

 /* more shared queuing code would be good; it should support
 * smarter scheduling, handle transaction translators, etc;
 * input size of periodic table to an interrupt scheduler.
 * (ohci 32, uhci 1024, ehci 256/512/1024).
 */

 /* The HC driver's private data is stored at the end of
 * this structure.
 */
 unsigned long hcd_priv[0]

 __attribute__ ((aligned (sizeof(unsigned long))));
 };

 

int hcd_buffer_create(struct usb_hcd *hcd)
{
 char name[16];
 int i, size;

 if (!hcd->self.controller->dma_mask)
 return 0;

 for (i = 0; i < HCD_BUFFER_POOLS; i++) {
 if (!(size = pool_max [i]))
 continue;
 snprintf(name, sizeof name, "buffer-%d", size);
 hcd->pool[i] = dma_pool_create(name, hcd->self.controller,
 size, size, 0);
 if (!hcd->pool [i]) {
	 hcd_buffer_destroy(hcd);
 	return -ENOMEM;
 	}
 }
 return 0;
}

首先要判断下这个主机控制器支持不支持DAM,如果支持DMA,就逐个适用dma_pool_alloc 来创建DMA 池,如果创建失败了,就调用同一个文件里的hcd_buffer_destroy 来将已经创建成功的池子给销毁掉。

void hcd_buffer_destroy(struct usb_hcd *hcd)
 {
 int i;


 for (i = 0; i < HCD_BUFFER_POOLS; i++) {
 	struct dma_pool *pool = hcd->pool[i];
 	if (pool) {
	 dma_pool_destroy(pool);
	 hcd->pool[i] = NULL;
	 }
   }
 }

一个用来取内存,一个用来释放内存。

void *hcd_buffer_alloc(struct usb_bus *bus,size_t size,gfp_t mem_flags,dma_addr_t *dma)
 {
 struct usb_hcd *hcd = bus_to_hcd(bus);
 int i;

 /* some USB hosts just use PIO */
 if (!bus->controller->dma_mask) {
	 *dma = ~(dma_addr_t) 0;
 	return kmalloc(size, mem_flags);
 	}

 for (i = 0; i < HCD_BUFFER_POOLS; i++) {
	 if (size <= pool_max [i])
	 return dma_pool_alloc(hcd->pool [i], mem_flags, dma);
 	}
     return dma_alloc_coherent(hcd->self.controller, size, dma, 0);
 }

 void hcd_buffer_free(struct usb_bus *bus,size_t size,void *addr,dma_addr_t dma)
{
 struct usb_hcd *hcd = bus_to_hcd(bus);
 int i;

 if (!addr)
 return;

 if (!bus->controller->dma_mask) {
 kfree(addr);
 return;
 }

 for (i = 0; i < HCD_BUFFER_POOLS; i++) {
 if (size <= pool_max [i]) {
 dma_pool_free(hcd->pool [i], addr, dma);
 return;
	 }
 }
 dma_free_coherent(hcd->self.controller, size, addr, dma);
}




 

你可能感兴趣的:(USB Core 七)