基于MSM8260的Android4.0.4 USB子系统分析(3)

接着上一篇看,第三大设备控制器的注册:
//Devices-msm8x60.c (arch\arm\mach-msm)
//udc设备控制器注册
static u64 dma_mask = 0xffffffffULL;
struct platform_device    msm_device_gadget_peripheral = {//usb设备控制器平台设备
 .name = "msm_hsusb",
 .id  = -1,
 .dev = {
  .dma_mask   = &dma_mask,
  .coherent_dma_mask = 0xffffffffULL,
 },
};
//Board-msm8x60.c (arch\arm\mach-msm)
//usb设备控制器平台数据
static struct msm_hsusb_gadget_platform_data    msm_gadget_pdata = {
 .is_phy_status_timer_on = 1,
};
//挂载usb设备控制器平台数据
msm_device_gadget_peripheral.dev.platform_data = &msm_gadget_pdata;
static struct platform_device *surf_devices[] __initdata = {
 .............
 &msm_device_gadget_peripheral,
}
//注册平台设备
static void __init msm8x60_init(struct msm_board_data *board_data)
{
 platform_add_devices(surf_devices,ARRAY_SIZE(surf_devices));//把usb设备控制器加入到系统中
}

//Msm72k_udc.c (drivers\usb\gadget)
//udc设备控制器平台驱动注册
static struct platform_driver usb_driver = {
 .probe  = msm72k_probe,
 .driver = { .name = "msm_hsusb",
      .pm = &msm72k_udc_dev_pm_ops, },
};
static int __init init(void)
{
 return platform_driver_register(&usb_driver);//注册usb平台驱动
}
module_init(init);
//设备控制器和设备控制器驱动匹配成功后,调用msm72k_probe
/*在分析前先看下udc设备控制器所使用的结构,一个udc控制器所用的资源都放在该结构中*/
struct usb_info {
 /* lock for register/queue/device state changes */
 spinlock_t lock;
 /* single request used for handling setup transactions */
 struct usb_request *setup_req;//处理枚举用的request
 struct platform_device *pdev;//存放注册的usb设备控制器平台设备结构体
 int irq;
 void *addr;
 unsigned state;
 unsigned flags;
 atomic_t configured;
 atomic_t running;
 struct dma_pool *pool;//dma池
 /* dma page to back the queue heads and items */
 unsigned char *buf;//传输用的buf
 dma_addr_t dma;//该buf对应的dma
 struct ept_queue_head *head;
 /* used for allocation */
 unsigned next_item;
 unsigned next_ifc_num;
 /* endpoints are ordered based on their status bits,  so they are OUT0, OUT1, ... OUT15, IN0, IN1, ... IN15*/
 struct msm_endpoint ept[32];//该usb设备控制器所拥有的端点
 /* max power requested by selected configuration */
 unsigned b_max_pow;
 unsigned chg_current;
 struct delayed_work chg_det;
 struct delayed_work chg_stop;
 struct msm_hsusb_gadget_platform_data *pdata;//存放对应usb平台设备的平台数据
 struct work_struct phy_status_check;
 struct work_struct work;//重要的work
 unsigned phy_status;
 unsigned phy_fail_count;
 unsigned prime_fail_count;
 unsigned long dTD_update_fail_count;
 struct usb_gadget   gadget;//支持的gadget
 struct usb_gadget_driver *driver;//该gadget的driver
 struct switch_dev sdev;
 /*下面是该gadget的0端点*/
 #define ep0out ept[0]
 #define ep0in  ept[16]
 atomic_t ep0_dir;
 atomic_t test_mode;
 atomic_t offline_pending;
 atomic_t softconnect;
 ..............
 atomic_t remote_wakeup;
 atomic_t self_powered;
 struct delayed_work rw_work;
 struct otg_transceiver *xceiv;
 enum usb_device_state usb_state;
 struct wake_lock wlock;
};
static int msm72k_probe(struct platform_device *pdev)
{
 struct usb_info *ui;
 struct msm_otg *otg;
 int retval;
 dev_dbg(&pdev->dev, "msm72k_probe\n");
 ui = kzalloc(sizeof(struct usb_info), GFP_KERNEL);//分配usb_info结构体
 ui->pdev = pdev;//存放注册的usb设备控制器平台设备结构体
 ui->pdata = pdev->dev.platform_data;//usb平台设备的平台数据
 ui->buf  = dma_alloc_coherent(&pdev->dev, 4096, &ui->dma, GFP_KERNEL);//分配dma buf返回虚拟地址赋给buf
 ui->pool = dma_pool_create("msm72k_udc", NULL, 32, 32, 0);//创建dma池
 ui->xceiv = otg_get_transceiver();//获得otg transceiver
 otg = to_msm_otg(ui->xceiv);
 ui->addr = otg->regs;//取出otg设备的寄存器
 ui->gadget.ops = &msm72k_ops;//gadget的操作函数
 ui->gadget.is_dualspeed = 1;//设置支持双速full/high speed
 device_initialize(&ui->gadget.dev);
 dev_set_name(&ui->gadget.dev, "gadget");
 ui->gadget.dev.parent = &pdev->dev;
 ui->gadget.dev.dma_mask = pdev->dev.dma_mask;
 /*switch work初始化和注册*/
 ui->sdev.name = DRIVER_NAME;//#define DRIVER_NAME "MSM72K_UDC"
 ui->sdev.print_name = print_switch_name;
 ui->sdev.print_state = print_switch_state;
 retval = switch_dev_register(&ui->sdev);
 the_usb_info = ui;//保存到全局变量the_usb_info
 wake_lock_init(&ui->wlock,WAKE_LOCK_SUSPEND, "usb_bus_active");//初始化wakelake
 usb_prepare(ui);//下面分析1
 retval = otg_set_peripheral(ui->xceiv, &ui->gadget);//设置otg收发器的gadget成员,调用otg的回调函数
 pm_runtime_enable(&pdev->dev);
 /* Setup phy stuck timer */
 if (ui->pdata && ui->pdata->is_phy_status_timer_on)//起一个定时器,以防phy挂掉
  setup_timer(&phy_status_timer, usb_phy_status_check_timer, 0);
 return 0;
}
1.下面看下usb_prepare()函数
static void usb_prepare(struct usb_info *ui)
{
 spin_lock_init(&ui->lock);//初始化ui的自旋锁
 memset(ui->buf, 0, 4096);//重置分配的dma buffer
 ui->head = (void *) (ui->buf + 0);//usb传输用的head头
 /* only important for reset/reinit */
 memset(ui->ept, 0, sizeof(ui->ept));
 ui->next_item = 0;
 ui->next_ifc_num = 0;
 init_endpoints(ui);//初始化端点,1.1
 /*初始化默认端点的最大包大小*/
 ui->ep0in.ep.maxpacket = 64;
 ui->ep0out.ep.maxpacket = 64;
 //#define SETUP_BUF_SIZE 8。分析见下面1.2
 ui->setup_req = usb_ept_alloc_req(&ui->ep0in, SETUP_BUF_SIZE, GFP_KERNEL);
 /*初始化后面要用到的work*/
 INIT_WORK(&ui->work, usb_do_work);//重要的work
 INIT_DELAYED_WORK(&ui->chg_det, usb_chg_detect);
 INIT_DELAYED_WORK(&ui->chg_stop, usb_chg_stop);
 INIT_DELAYED_WORK(&ui->rw_work, usb_do_remote_wakeup);
 if (ui->pdata && ui->pdata->is_phy_status_timer_on)//监视phy是否挂掉的定时器,初始化为1
   INIT_WORK(&ui->phy_status_check, usb_phy_stuck_recover);//如果phy挂掉,则reset硬件恢复
}
1.1 初始化端点
static void init_endpoints(struct usb_info *ui)
{
 unsigned n;
 for (n = 0; n < 32; n++) {
  struct msm_endpoint *ept = ui->ept + n;//初始化每个端点
  ept->ui = ui;//把ui设备控制器的信息保存到端点,方便以后用
  ept->bit = n;//每个端点的bit总编号
  ept->num = n & 15;//每个端点的端点号
  ept->ep.name = ep_name[n];//每个端点的名字
  ept->ep.ops = &msm72k_ep_ops;//端点操作函数
  //buf的顺序为ep1in,ep1out
  if (ept->bit > 15) {
   /* IN endpoint */
   ept->head = ui->head + (ept->num << 1) + 1;//初始化端点真实传输的buffer队列
   ept->flags = EPT_FLAG_IN;//是in端点
  } else {
   /* OUT endpoint */
   ept->head = ui->head + (ept->num << 1);//分配传输buf
   ept->flags = 0;//是out端点
  }
  //设定timer,处理endpoint数据是否发送成功
  setup_timer(&ept->prime_timer, ept_prime_timer_func, (unsigned long) ept);
 }
}
//下面分析该请求结构体的关系
struct msm_request {
 struct usb_request req;//下面该结构体(5)
 /* saved copy of req.complete */
 void   (*gadget_complete)(struct usb_ep *ep,struct usb_request *req);
 struct usb_info *ui;
 struct msm_request *next;
 struct msm_request *prev;
 unsigned busy:1;
 unsigned live:1;
 unsigned alloced:1;//是否分配过req.buf内存

 dma_addr_t dma;
  /*从dma池中分配item结构体,对应的item dma放在item_dma变量中*/
 dma_addr_t item_dma;
 struct ept_queue_item *item;
};
//上接上面的(5)
struct usb_request {
 void   *buf;
 unsigned  length;
 dma_addr_t  dma;
 unsigned  no_interrupt:1;
 unsigned  zero:1;
 unsigned  short_not_ok:1;
 void   (*complete)(struct usb_ep *ep, struct usb_request *req);
 void   *context;
 struct list_head list;
 int    status;
 unsigned  actual;
 unsigned  udc_priv;
};
1.2 为端点分配req
struct usb_request *usb_ept_alloc_req(struct msm_endpoint *ept, unsigned bufsize, gfp_t gfp_flags)
{
 struct usb_info *ui = ept->ui;
 struct msm_request *req;
 req = kzalloc(sizeof(*req), gfp_flags);//分配req
 req->item = dma_pool_alloc(ui->pool, gfp_flags, &req->item_dma);//从前面的dma池中分配dma内存
 if (bufsize) {
  req->req.buf = kmalloc(bufsize, gfp_flags);
  req->alloced = 1;
 }
 return &req->req;
}
2.设置otg收发器的gadget成员
dev->otg.set_peripheral = msm_otg_set_peripheral;//初始化otg控制器的回调函数
otg_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *periph)
{
 return otg->set_peripheral(otg, periph);
}
static int msm_otg_set_peripheral(struct otg_transceiver *xceiv, struct usb_gadget *gadget)
{
 struct msm_otg *dev = container_of(xceiv, struct msm_otg, otg);
 ....................
 dev->otg.gadget = gadget;//初始化收发器
 pr_info("peripheral driver registered w/ tranceiver\n");
 wake_lock(&dev->wlock);
 queue_work(dev->wq, &dev->sm_work);//调度msm_otg_sm_work,otg状态机第一个调用的地方,开启一个新的时代
 return 0;
}
现在三大设备控制器都注册完了,下一节看下如何配合。
posted @ 2015-07-26 18:10  zxiaocheng  阅读(246)  评论(0)    收藏  举报