struct spike_dev {
spinlock_t spi_lock;
- struct semaphore spi_sem;
struct semaphore fop_sem;
dev_t devt;
struct cdev cdev;
//
/**** 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受信データ リングバッファ ******************************************
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;
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:
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;
}
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);
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();