static void spi_worker_thread(void *arg) { struct _spi_device_st *spi_device = spi_dev; struct _smsspi_txmsg *msg = NULL; struct _spi_msg txmsg; //int i=0; static DEFINE_MUTEX(lock); // add by jiabf 20100730 PDEBUG("worker start\n"); do { mutex_lock(&lock); /* do we have a msg to write ? */ if (!msg && !list_empty(&spi_device->txqueue)) msg = (struct _smsspi_txmsg *) list_entry(spi_device->txqueue. next, struct _smsspi_txmsg, node); if (msg) { if (msg->add_preamble) { txmsg.len = min(msg->size + sizeof(smsspi_preamble), (size_t) TX_BUFFER_SIZE); txmsg.buf = spi_device->txbuf; txmsg.buf_phy_addr = spi_device->txbuf_phy_addr; memcpy(txmsg.buf, smsspi_preamble, sizeof(smsspi_preamble)); memcpy(&txmsg.buf[sizeof(smsspi_preamble)], msg->buffer, txmsg.len - sizeof(smsspi_preamble)); msg->add_preamble = 0; msg->buffer = (char*)msg->buffer + txmsg.len - sizeof(smsspi_preamble); msg->size -= txmsg.len - sizeof(smsspi_preamble); /* zero out the rest of aligned buffer */ memset(&txmsg.buf[txmsg.len], 0, TX_BUFFER_SIZE - txmsg.len); if(spi_resume_fail||spi_suspended) { printk(KERN_EMERG " SMS1180: spi failed\n") ; } else { smsspi_common_transfer_msg(&spi_device->dev, &txmsg, 1); } } else { txmsg.len = min(msg->size, (size_t) TX_BUFFER_SIZE); txmsg.buf = spi_device->txbuf; txmsg.buf_phy_addr = spi_device->txbuf_phy_addr; memcpy(txmsg.buf, msg->buffer, txmsg.len); msg->buffer = (char*)msg->buffer + txmsg.len; msg->size -= txmsg.len; /* zero out the rest of aligned buffer */ memset(&txmsg.buf[txmsg.len], 0, TX_BUFFER_SIZE - txmsg.len); if(spi_resume_fail||spi_suspended) { printk(KERN_EMERG " SMS1180: spi failed\n") ; } else { smsspi_common_transfer_msg(&spi_device->dev, &txmsg, 0); } } } else { if(spi_resume_fail||spi_suspended) { printk(KERN_EMERG " SMS1180: spi failed\n") ; } else { smsspi_common_transfer_msg(&spi_device->dev, NULL, 1); } } /* if there was write, have we finished ? */ if (msg && !msg->size) { /* call postwrite call back */ if (msg->postwrite) msg->postwrite(spi_device); list_del(&msg->node); complete(&msg->completion); msg = NULL; } /* if there was read, did we read anything ? */ //check if we lost msg, if so, recover if(g_Sms_MsgFound_Counter<g_Sms_Int_Counter) { printk("we lost msg, probably becouse dma time out\n"); //for(i=0; i<16; i++) { //smsspi_common_transfer_msg(&spi_device->dev, NULL, 1); } g_Sms_MsgFound_Counter = g_Sms_Int_Counter; } mutex_unlock(&lock); } while (!list_empty(&spi_device->txqueue) || msg); // PDEBUG("worker end\n"); }
static void spi_worker_thread(void *arg) { struct _spi_device_st *spi_device = spi_dev; struct _smsspi_txmsg *msg = NULL; struct _spi_msg txmsg; PDEBUG("worker start\n"); do { /* do we have a msg to write ? */ if (!msg && !list_empty(&spi_device->txqueue)) msg = (struct _smsspi_txmsg *) list_entry(spi_device->txqueue. next, struct _smsspi_txmsg, node); if (msg) { if (msg->add_preamble) { txmsg.len = min(msg->size + sizeof(smsspi_preamble), (size_t) TX_BUFFER_SIZE); txmsg.buf = spi_device->txbuf; txmsg.buf_phy_addr = spi_device->txbuf_phy_addr; memcpy(txmsg.buf, smsspi_preamble, sizeof(smsspi_preamble)); memcpy(&txmsg.buf[sizeof(smsspi_preamble)], msg->buffer, txmsg.len - sizeof(smsspi_preamble)); msg->add_preamble = 0; msg->buffer += txmsg.len - sizeof(smsspi_preamble); msg->size -= txmsg.len - sizeof(smsspi_preamble); /* zero out the rest of aligned buffer */ memset(&txmsg.buf[txmsg.len], 0, TX_BUFFER_SIZE - txmsg.len); smsspi_common_transfer_msg(&spi_device->dev, &txmsg, 1); } else { txmsg.len = min(msg->size, (size_t) TX_BUFFER_SIZE); txmsg.buf = spi_device->txbuf; txmsg.buf_phy_addr = spi_device->txbuf_phy_addr; memcpy(txmsg.buf, msg->buffer, txmsg.len); msg->buffer += txmsg.len; msg->size -= txmsg.len; /* zero out the rest of aligned buffer */ memset(&txmsg.buf[txmsg.len], 0, TX_BUFFER_SIZE - txmsg.len); smsspi_common_transfer_msg(&spi_device->dev, &txmsg, 0); } } else { smsspi_common_transfer_msg(&spi_device->dev, NULL, 1); } /* if there was write, have we finished ? */ if (msg && !msg->size) { /* call postwrite call back */ if (msg->postwrite) msg->postwrite(spi_device); list_del(&msg->node); complete(&msg->completion); msg = NULL; } /* if there was read, did we read anything ? */ } while (!list_empty(&spi_device->txqueue) || msg); PDEBUG("worker end\n"); }