OSDN Git Service

add semaphore for spi_txbuf
authorNaoya Takamura <ntaka206@users.sourceforge.jp>
Fri, 16 Dec 2011 02:21:50 +0000 (11:21 +0900)
committerNaoya Takamura <ntaka206@users.sourceforge.jp>
Fri, 16 Dec 2011 02:21:50 +0000 (11:21 +0900)
spike-ad.c

index fb8fca1..2332cf6 100644 (file)
@@ -92,7 +92,6 @@ static struct irq_device irq_dev;
 
 struct spike_dev {
        spinlock_t spi_lock;
-       struct semaphore spi_sem;
        struct semaphore fop_sem;
        dev_t devt;
        struct cdev cdev;
@@ -120,10 +119,18 @@ DECLARE_TASKLET(spike_tasklet, spike_tasklet_func, 0);
 //
 /**** SPI送信データ バッファ ******************************************
 */
-// 送信データ(CMD for PIC)
-#define        SPI_TX_MAX      (64)
-static unsigned char   spitxbuf[SPI_TX_MAX];
-static int     spi_tx_len;
+#define        SPI_TX_MAX      (64)    // SPI送信データの最大長
+
+// 送信データバッファ(CMD for PIC)
+typedef struct {
+       unsigned char   txbuf[SPI_TX_MAX];
+       int     tx_len; // SPIで送信するデータ長
+       struct semaphore txbuf_sem;
+} SpiTxBuf;
+
+static SpiTxBuf        spi_txbuf;
+
+
 
 //
 /**** SPI受信データ リングバッファ ******************************************
@@ -255,15 +262,17 @@ static int spike_queue_spi_write(void)
        spike_ctl.msg.complete = spike_spi_completion_handler;
        spike_ctl.msg.context = NULL;
 
-       /* write some toggling bit patterns, doesn't really matter */   
        memset(spike_ctl.tx_buff, 0, SPI_BUFF_SIZE);
-       spike_ctl.tx_buff[0] = '$';
+//     spike_ctl.tx_buff[0] = '$';
        memset(spike_ctl.rx_buff, 0, SPI_BUFF_SIZE);
 
-       // TXコマンドセット
-       memcpy(spike_ctl.tx_buff, spitxbuf, spi_tx_len);
-       // TXコマンドクリア
-       memset(spitxbuf, 0, SPI_TX_MAX);
+       if (down_interruptible(&spi_txbuf.txbuf_sem)) 
+               return -ERESTARTSYS;
+               // TXコマンドセット
+               memcpy(spike_ctl.tx_buff, spi_txbuf.txbuf, spi_txbuf.tx_len);
+               // TXコマンドクリア
+               memset(spi_txbuf.txbuf, 0, SPI_TX_MAX);
+       up(&spi_txbuf.txbuf_sem);
 
        spike_ctl.transfer.tx_buf = spike_ctl.tx_buff;
        spike_ctl.transfer.rx_buf = spike_ctl.rx_buff;
@@ -466,20 +475,28 @@ static long spike_file_ioctl(struct file *file, unsigned int cmd, unsigned long
        switch(cmd) {
        // SPI送信データ長セット
        case CMD_TX_LEN:
-               if (copy_from_user(&spi_tx_len, (void *)arg, sizeof(int))) {
+               if (down_interruptible(&spi_txbuf.txbuf_sem)) 
+                       return -ERESTARTSYS;
+               if (copy_from_user(&spi_txbuf.tx_len, (void *)arg, sizeof(int))) {
                        printk(KERN_ALERT "spike_file_ioctl(): copy_from_user() failed\n");
+                       up(&spi_txbuf.txbuf_sem);
                        return -EFAULT;
                }
-printk(KERN_INFO "spike_file_ioctl: CMD_TX_LEN %d\n", spi_tx_len);
-               if (spi_tx_len > SPI_TX_MAX) spi_tx_len = SPI_TX_MAX;
+printk(KERN_INFO "spike_file_ioctl: CMD_TX_LEN %d\n", spi_txbuf.tx_len);
+               if (spi_txbuf.tx_len > SPI_TX_MAX) spi_txbuf.tx_len = SPI_TX_MAX;
+               up(&spi_txbuf.txbuf_sem);
                return 0;
        // SPI送信データセット
        case CMD_TX_SET:
-               if (copy_from_user(&spitxbuf, (void *)arg, spi_tx_len)) {
+               if (down_interruptible(&spi_txbuf.txbuf_sem)) 
+                       return -ERESTARTSYS;
+               if (copy_from_user(&spi_txbuf.txbuf, (void *)arg, spi_txbuf.tx_len)) {
                        printk(KERN_ALERT "spike_file_ioctl(): copy_from_user() failed\n");
+                       up(&spi_txbuf.txbuf_sem);
                        return -EFAULT;
                }
-printk(KERN_INFO "spike_file_ioctl: CMD_TX_SET %02X %02X %02X %02X\n", spitxbuf[0], spitxbuf[1], spitxbuf[2], spitxbuf[3]);
+printk(KERN_INFO "spike_file_ioctl: CMD_TX_SET %02X %02X %02X %02X\n", spi_txbuf.txbuf[0], spi_txbuf.txbuf[1], spi_txbuf.txbuf[2], spi_txbuf.txbuf[3]);
+               up(&spi_txbuf.txbuf_sem);
                return 0;
        // SPI受信データ返す
        case CMD_RX_GET:
@@ -530,24 +547,22 @@ static const struct file_operations spike_fops = {
 
 static int spike_probe(struct spi_device *spi_device)
 {
-       if (down_interruptible(&spike_dev.spi_sem))
-               return -EBUSY;
+       unsigned long flags;
 
+       spin_lock_irqsave(&spike_dev.spi_lock, flags);
        spike_dev.spi_device = spi_device;
-
-       up(&spike_dev.spi_sem);
+       spin_unlock_irqrestore(&spike_dev.spi_lock, flags);
 
        return 0;
 }
 
 static int spike_remove(struct spi_device *spi_device)
 {
-       if (down_interruptible(&spike_dev.spi_sem))
-               return -EBUSY;
-       
-       spike_dev.spi_device = NULL;
+       unsigned long flags;
 
-       up(&spike_dev.spi_sem);
+       spin_lock_irqsave(&spike_dev.spi_lock, flags);
+       spike_dev.spi_device = NULL;
+       spin_unlock_irqrestore(&spike_dev.spi_lock, flags);
 
        return 0;
 }
@@ -816,7 +831,6 @@ static int __init spike_init(void)
        memset(&spike_dev, 0, sizeof(spike_dev));
        memset(&spike_ctl, 0, sizeof(spike_ctl));
 
-       sema_init(&spike_dev.spi_sem, 1);
        sema_init(&spike_dev.fop_sem, 1);
        spin_lock_init(&spike_dev.spi_lock);
 
@@ -824,10 +838,10 @@ static int __init spike_init(void)
        sema_init(&irq_dev.sem, 1);
 
        // TXコマンドクリア
-       memset(spitxbuf, 0, SPI_TX_MAX);
+       memset(&spi_txbuf, 0, sizeof(spi_txbuf));
+       sema_init(&spi_txbuf.txbuf_sem, 1);
 
        finfo.f_version = 0;            // 未使用マーク
-       spi_tx_len = 0;
        // リングバッファ初期化
        ring_init();