572至574行,分配內存,注意對象的類型是struct spidev_data,看下它在drivers/spi/spidev.c中的定義:
00000075 struct spidev_data { 00000076 dev_t devt; 00000077 spinlock_t spi_lock; 00000078 struct spi_device *spi; 00000079 struct list_head device_entry; 00000080 00000081 /* buffer is NULL unless this device is open (users > 0) */ 00000082 struct mutex buf_lock; 00000083 unsigned users; 00000084 u8 *buffer; 00000085 };
76行,設備號。79行,設備鏈表,所有采用此驅動的設備將連成一個鏈表。83行,計數,也即是此設備被open的次數。
回到spidev_probe函數,577至586行,一些鎖和鏈表的初始化。588行,從名字上就可以知道,就是找到第一個為0的位,第一個參數minors的定義:
00000054 #define N_SPI_MINORS 32 /* ... up to 256 */ 00000055 00000056 static DECLARE_BITMAP(minors, N_SPI_MINORS);
DECLARE_BITMAP是一個宏,定義如下:
#define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)]
將宏展開后是這樣的,unsigned long minors[1],其實就是定義一個只有一個元素的無符號長整形數組miniors。
590至593行,如果找到了非0位,就將它作為次設備號與之前注冊的主設備號生成設備號。
595至598行,創建設備,並生成設備節點,設備節點在/dev目錄下,名字的形式為“spidevx.x”。
603至608行,創建設備成功后,將相應的位置1,表示該次設備號已經被使用,同時將該設備加入到設備鏈表。
611至614行,將設備的私有數據指針指向該設備。
至此,SPI設備驅動的初始化過程也說完了。下面就以應用程序的操作順序來說,假設是從open-->write這個過程。下面先看驅動中open函數的實現,同樣在drivers/spi/spidev.c:
00000477 static int spidev_open(struct inode *inode, struct file *filp) 00000478 { 00000479 struct spidev_data *spidev; 00000480 int status = -ENXIO; 00000481 00000482 mutex_lock(&device_list_lock); 00000483 00000484 00000485 list_for_each_entry(spidev, &device_list, device_entry) { 00000486 if (spidev->devt == inode->i_rdev) { 00000487 status = 0; 00000488 break; 00000489 } 00000490 } 00000491 if (status == 0) { 00000492 if (!spidev->buffer) { 00000493 spidev->buffer = kmalloc(bufsiz, GFP_KERNEL); 00000494 if (!spidev->buffer) { 00000495 dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); 00000496 status = -ENOMEM; 00000497 } 00000498 } 00000499 if (status == 0) { 00000500 spidev->users++; 00000501 filp->private_data = spidev; 00000502 nonseekable_open(inode, filp); 00000503 } 00000504 } else 00000505 pr_debug("spidev: nothing for minor %d\n", iminor(inode)); 00000506 00000507 mutex_unlock(&device_list_lock); 00000508 return status; 00000509 }
485至490行,遍歷設備鏈表,每找到一個設備就將它的設備號與打開文件的設備號進行比較,相等的話表示查找成功。
491至505行,查找成功后就分配讀寫數據內存,使用計數加1,設置文件私有數據指針指向查找到的設備,以后在驅動的write、read函數里就可以把它取出來。
接下來是write函數的定義:
00000190 static ssize_t 00000191 spidev_write(struct file *filp, const char __user *buf, 00000192 size_t count, loff_t *f_pos) 00000193 { 00000194 struct spidev_data *spidev; 00000195 ssize_t status = 0; 00000196 unsigned long missing; 00000197 00000198 /* chipselect only toggles at start or end of operation */ 00000199 if (count > bufsiz) 00000200 return -EMSGSIZE; 00000201 00000202 spidev = filp->private_data; 00000203 00000204 mutex_lock(&spidev->buf_lock); 00000205 missing = copy_from_user(spidev->buffer, buf, count); 00000206 if (missing == 0) { 00000207 status = spidev_sync_write(spidev, count); 00000208 } else 00000209 status = -EFAULT; 00000210 mutex_unlock(&spidev->buf_lock); 00000211 00000212 return status; 00000213 }
199至200行,應用程序寫入的數據不能大於驅動中緩沖區的大小,默認為4096個字節。
202行,指向文件的私有數據。
205行,拷貝用戶空間的數據到內核空間。
207行,spidev_sync_write的定義:
00000130 static inline ssize_t 00000131 spidev_sync_write(struct spidev_data *spidev, size_t len) 00000132 { 00000133 struct spi_transfer t = { 00000134 .tx_buf = spidev->buffer, 00000135 .len = len, 00000136 }; 00000137 struct spi_message m; 00000138 00000139 spi_message_init(&m); 00000140 spi_message_add_tail(&t, &m); 00000141 return spidev_sync(spidev, &m); 00000142 }
133行,struct spi_transfer的定義在include/linux/spi/spi.h:
00000427 struct spi_transfer { 00000428 /* it's ok if tx_buf == rx_buf (right?) 00000429 * for MicroWire, one buffer must be null 00000430 * buffers must work with dma_*map_single() calls, unless 00000431 * spi_message.is_dma_mapped reports a pre-existing mapping 00000432 */ 00000433 const void *tx_buf; 00000434 void *rx_buf; 00000435 unsigned len; 00000436 00000437 dma_addr_t tx_dma; 00000438 dma_addr_t rx_dma; 00000439 00000440 unsigned cs_change:1; 00000441 u8 bits_per_word; 00000442 u16 delay_usecs; 00000443 u32 speed_hz; 00000444 00000445 struct list_head transfer_list; 00000446 };
433至435行,發送、接收緩沖區和長度。437和438行,發送和接收的DMA地址。
440行,傳輸完成后是否改變片選信號。
441行,如果為0則使用驅動的默認值。
442行,傳輸完成后等待多長時間(毫秒)再改變片選信號。
443行,將多個傳輸連成一個鏈表。
回到spidev_sync_write函數的137行,在spi.h中定義的struct spi_message:
00000476 struct spi_message { 00000477 struct list_head transfers; 00000478 00000479 struct spi_device *spi; 00000480 00000481 unsigned is_dma_mapped:1; 00000482 00000483 /* REVISIT: we might want a flag affecting the behavior of the 00000484 * last transfer ... allowing things like "read 16 bit length L" 00000485 * immediately followed by "read L bytes". Basically imposing 00000486 * a specific message scheduling algorithm. 00000487 * 00000488 * Some controller drivers (message-at-a-time queue processing) 00000489 * could provide that as their default scheduling algorithm. But 00000490 * others (with multi-message pipelines) could need a flag to 00000491 * tell them about such special cases. 00000492 */ 00000493 00000494 /* completion is reported through a callback */ 00000495 void (*complete)(void *context); 00000496 void *context; 00000497 unsigned actual_length; 00000498 int status; 00000499 00000500 /* for optional use by whatever driver currently owns the 00000501 * spi_message ... between calls to spi_async and then later 00000502 * complete(), that's the spi_master controller driver. 00000503 */ 00000504 struct list_head queue; 00000505 void *state; 00000506 };
477行,一個message可能包含多個transfer,因此用鏈表將這些transfer連起來。
479行,這次message所使用的spi設備。
481行,是否采用DMA的標志。
495行,傳輸完成后的回調函數指針。496行,回調函數的參數。
497行,這次message成功傳輸的字節數。
504和505行,當前驅動擁有的message。
回到spidev_sync_write函數,139行,spi.h中的內聯函數spi_message_init:
00000508 static inline void spi_message_init(struct spi_message *m) 00000509 { 00000510 memset(m, 0, sizeof *m); 00000511 INIT_LIST_HEAD(&m->transfers); 00000512 }
很簡單,清0內存和初始化message的transfer鏈表。
140行,spi_message_add_tail也是spi.h中的內聯函數:
00000514 static inline void 00000515 spi_message_add_tail(struct spi_transfer *t, struct spi_message *m) 00000516 { 00000517 list_add_tail(&t->transfer_list, &m->transfers); 00000518 }
將transfer加入到鏈表尾。
141行,spidev_sync函數是在drivers/spi/spidev.c中定義的:
00000105 static ssize_t 00000106 spidev_sync(struct spidev_data *spidev, struct spi_message *message) 00000107 { 00000108 DECLARE_COMPLETION_ONSTACK(done); 00000109 int status; 00000110 00000111 message->complete = spidev_complete; 00000112 message->context = &done; 00000113 00000114 spin_lock_irq(&spidev->spi_lock); 00000115 if (spidev->spi == NULL) 00000116 status = -ESHUTDOWN; 00000117 else 00000118 status = spi_async(spidev->spi, message); 00000119 spin_unlock_irq(&spidev->spi_lock); 00000120 00000121 if (status == 0) { 00000122 wait_for_completion(&done); 00000123 status = message->status; 00000124 if (status == 0) 00000125 status = message->actual_length; 00000126 } 00000127 return status; 00000128 }
108行,定義並初始化一個完成量,完成量是Linux的一種同步機制。
111行,spidev_complete函數里就用來喚醒等待completion,定義如下:
00000100 static void spidev_complete(void *arg) 00000101 { 00000102 complete(arg); 00000103 }
112行,作為spidev_complete函數的參數。
118行,調用drivers/spi/spi.c里的spi_async函數,從函數名知道,這是異步實現的。為什么是異步的?往下看就知道了。
00000737 int spi_async(struct spi_device *spi, struct spi_message *message) 00000738 { 00000739 struct spi_master *master = spi->master; 00000740 int ret; 00000741 unsigned long flags; 00000742 00000743 spin_lock_irqsave(&master->bus_lock_spinlock, flags); 00000744 00000745 if (master->bus_lock_flag) 00000746 ret = -EBUSY; 00000747 else 00000748 ret = __spi_async(spi, message); 00000749 00000750 spin_unlock_irqrestore(&master->bus_lock_spinlock, flags); 00000751 00000752 return ret; 00000753 }
745行,如果master所在的總線被鎖住了,那么就返回忙。
748行,看__spi_async函數的定義:
00000679 static int __spi_async(struct spi_device *spi, struct spi_message *message) 00000680 { 00000681 struct spi_master *master = spi->master; 00000682 00000683 /* Half-duplex links include original MicroWire, and ones with 00000684 * only one data pin like SPI_3WIRE (switches direction) or where 00000685 * either MOSI or MISO is missing. They can also be caused by 00000686 * software limitations. 00000687 */ 00000688 if ((master->flags & SPI_MASTER_HALF_DUPLEX) 00000689 || (spi->mode & SPI_3WIRE)) { 00000690 struct spi_transfer *xfer; 00000691 unsigned flags = master->flags; 00000692 00000693 list_for_each_entry(xfer, &message->transfers, transfer_list) { 00000694 if (xfer->rx_buf && xfer->tx_buf) 00000695 return -EINVAL; 00000696 if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf) 00000697 return -EINVAL; 00000698 if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf) 00000699 return -EINVAL; 00000700 } 00000701 } 00000702 00000703 message->spi = spi; 00000704 message->status = -EINPROGRESS; 00000705 return master->transfer(spi, message); 00000706 }
688至701行,如果master設置了SPI_MASTER_HALF_DUPLEX標志,或者spi設備使用的是3線模式,那么就對message里的每一個transfer的發送和接收buf做一些檢查。
705行,調用的是具體的SPI控制器驅動里的函數,這里是drivers/spi/spi_s3c64xx.c里的s3c64xx_spi_transfer函數:
00000763 static int s3c64xx_spi_transfer(struct spi_device *spi, 00000764 struct spi_message *msg) 00000765 { 00000766 struct s3c64xx_spi_driver_data *sdd; 00000767 unsigned long flags; 00000768 00000769 sdd = spi_master_get_devdata(spi->master); 00000770 00000771 spin_lock_irqsave(&sdd->lock, flags); 00000772 00000773 if (sdd->state & SUSPND) { 00000774 spin_unlock_irqrestore(&sdd->lock, flags); 00000775 return -ESHUTDOWN; 00000776 } 00000777 00000778 msg->status = -EINPROGRESS; 00000779 msg->actual_length = 0; 00000780 00000781 list_add_tail(&msg->queue, &sdd->queue); 00000782 00000783 queue_work(sdd->workqueue, &sdd->work); 00000784 00000785 spin_unlock_irqrestore(&sdd->lock, flags); 00000786 00000787 return 0; 00000788 }