Loading drivers/char/diag/diag_usb.c +5 −0 Original line number Diff line number Diff line Loading @@ -520,6 +520,9 @@ int diag_usb_write(int id, unsigned char *buf, int len, int ctxt) usb_info = &diag_usb[id]; if (!atomic_read(&usb_info->connected)) return -ENOTCONN; if (len > usb_info->max_size) { DIAG_LOG(DIAG_DEBUG_MUX, "len: %d, max_size: %d\n", len, usb_info->max_size); Loading @@ -534,9 +537,11 @@ int diag_usb_write(int id, unsigned char *buf, int len, int ctxt) * trying to write more buffers than the max supported by * this particualar diag USB channel at any given instance, * or the previous write ptrs are stuck in the USB layer. * Remove the buffer entry from the usb buf table for this case. */ pr_err_ratelimited("diag: In %s, cannot retrieve USB write ptrs for USB channel %s\n", __func__, usb_info->name); diag_usb_buf_tbl_remove(usb_info, buf); return -ENOMEM; } Loading drivers/char/diag/diagfwd_bridge.c +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #endif #include "diagfwd_mhi.h" #include "diag_dci.h" #include "diag_ipc_logging.h" #ifdef CONFIG_MHI_BUS #define diag_mdm_init diag_mhi_init Loading drivers/char/diag/diagfwd_mhi.c +48 −21 Original line number Diff line number Diff line Loading @@ -83,7 +83,6 @@ struct diag_mhi_info diag_mhi[NUM_MHI_DEV] = { static int mhi_buf_tbl_add(struct diag_mhi_info *mhi_info, int type, void *buf, int len) { unsigned long flags; struct diag_mhi_buf_tbl_t *item; struct diag_mhi_ch_t *ch = NULL; Loading @@ -103,16 +102,14 @@ static int mhi_buf_tbl_add(struct diag_mhi_info *mhi_info, int type, return -EINVAL; } item = kzalloc(sizeof(struct diag_mhi_buf_tbl_t), GFP_KERNEL); item = kzalloc(sizeof(*item), GFP_ATOMIC); if (!item) return -ENOMEM; kmemleak_not_leak(item); spin_lock_irqsave(&ch->lock, flags); item->buf = buf; item->len = len; list_add_tail(&item->link, &ch->buf_tbl); spin_unlock_irqrestore(&ch->lock, flags); return 0; } Loading Loading @@ -166,7 +163,9 @@ static void mhi_buf_tbl_clear(struct diag_mhi_info *mhi_info) unsigned long flags; struct list_head *start, *temp; struct diag_mhi_buf_tbl_t *item = NULL; struct diag_mhi_buf_tbl_t *tp = NULL, *tp_temp = NULL; struct diag_mhi_ch_t *ch = NULL; unsigned char *buf; if (!mhi_info || !mhi_info->enabled) return; Loading @@ -180,9 +179,17 @@ static void mhi_buf_tbl_clear(struct diag_mhi_info *mhi_info) item = list_entry(start, struct diag_mhi_buf_tbl_t, link); list_del(&item->link); buf = item->buf; list_for_each_entry_safe(tp, tp_temp, &mhi_info->read_done_list, link) { if (tp->buf == buf) { list_del(&tp->link); kfree(tp); tp = NULL; } } diagmem_free(driver, item->buf, mhi_info->mempool); kfree(item); } spin_unlock_irqrestore(&ch->lock, flags); } Loading Loading @@ -348,9 +355,9 @@ static void mhi_read_done_work_fn(struct work_struct *work) do { if (!(atomic_read(&(mhi_info->read_ch.opened)))) break; spin_lock_irqsave(&mhi_info->lock, flags); spin_lock_irqsave(&mhi_info->read_ch.lock, flags); if (list_empty(&mhi_info->read_done_list)) { spin_unlock_irqrestore(&mhi_info->lock, flags); spin_unlock_irqrestore(&mhi_info->read_ch.lock, flags); break; } tp = list_first_entry(&mhi_info->read_done_list, Loading @@ -359,7 +366,7 @@ static void mhi_read_done_work_fn(struct work_struct *work) buf = tp->buf; len = tp->len; kfree(tp); spin_unlock_irqrestore(&mhi_info->lock, flags); spin_unlock_irqrestore(&mhi_info->read_ch.lock, flags); if (!buf) break; DIAG_LOG(DIAG_DEBUG_BRIDGE, Loading @@ -373,12 +380,15 @@ static void mhi_read_done_work_fn(struct work_struct *work) if ((atomic_read(&(mhi_info->read_ch.opened)))) { err = diag_remote_dev_read_done(mhi_info->dev_id, buf, len); if (err) if (err) { mhi_buf_tbl_remove(mhi_info, TYPE_MHI_READ_CH, buf, len); break; } } else { mhi_buf_tbl_remove(mhi_info, TYPE_MHI_READ_CH, buf, len); break; } } while (buf); } Loading @@ -400,22 +410,26 @@ static void mhi_read_work_fn(struct work_struct *work) do { if (!(atomic_read(&(read_ch->opened)))) break; spin_lock_irqsave(&read_ch->lock, flags); buf = diagmem_alloc(driver, DIAG_MDM_BUF_SIZE, mhi_info->mempool); if (!buf) { spin_unlock_irqrestore(&read_ch->lock, flags); if (!buf) break; } err = mhi_buf_tbl_add(mhi_info, TYPE_MHI_READ_CH, buf, DIAG_MDM_BUF_SIZE); if (err) if (err) { spin_unlock_irqrestore(&read_ch->lock, flags); goto fail; } DIAG_LOG(DIAG_DEBUG_BRIDGE, "queueing a read buf %pK, ch: %s\n", buf, mhi_info->name); spin_lock_irqsave(&read_ch->lock, flags); err = mhi_queue_transfer(mhi_info->mhi_dev, DMA_FROM_DEVICE, buf, DIAG_MDM_BUF_SIZE, mhi_flags); spin_unlock_irqrestore(&read_ch->lock, flags); Loading Loading @@ -475,12 +489,12 @@ static int mhi_write(int id, unsigned char *buf, int len, int ctxt) return -EIO; } spin_lock_irqsave(&ch->lock, flags); err = mhi_buf_tbl_add(&diag_mhi[id], TYPE_MHI_WRITE_CH, buf, len); if (err) goto fail; spin_lock_irqsave(&ch->lock, flags); err = mhi_queue_transfer(diag_mhi[id].mhi_dev, DMA_TO_DEVICE, buf, len, mhi_flags); spin_unlock_irqrestore(&ch->lock, flags); Loading Loading @@ -533,9 +547,11 @@ static void diag_mhi_read_cb(struct mhi_device *mhi_dev, struct mhi_result *result) { struct diag_mhi_info *mhi_info = NULL; struct diag_mhi_buf_tbl_t *tp; struct diag_mhi_buf_tbl_t *item = NULL; struct diag_mhi_buf_tbl_t *tp = NULL, *temp = NULL; unsigned long flags; void *buf = NULL; uint8_t queue_read = 0; if (!mhi_dev) return; Loading @@ -548,18 +564,29 @@ static void diag_mhi_read_cb(struct mhi_device *mhi_dev, return; if (atomic_read(&mhi_info->read_ch.opened) && result->transaction_status != -ENOTCONN) { spin_lock_irqsave(&mhi_info->read_ch.lock, flags); tp = kmalloc(sizeof(*tp), GFP_ATOMIC); if (!tp) { DIAG_LOG(DIAG_DEBUG_BRIDGE, "no mem for list\n"); spin_unlock_irqrestore(&mhi_info->read_ch.lock, flags); return; } list_for_each_entry_safe(item, temp, &mhi_info->read_ch.buf_tbl, link) { if (item->buf == buf) { tp->buf = buf; tp->len = result->bytes_xferd; spin_lock_irqsave(&mhi_info->lock, flags); list_add_tail(&tp->link, &mhi_info->read_done_list); spin_unlock_irqrestore(&mhi_info->lock, flags); queue_work(mhi_info->mhi_wq, &(mhi_info->read_done_work)); list_add_tail(&tp->link, &mhi_info->read_done_list); queue_read = 1; break; } } spin_unlock_irqrestore(&mhi_info->read_ch.lock, flags); if (queue_read) queue_work(mhi_info->mhi_wq, &(mhi_info->read_done_work)); } else { mhi_buf_tbl_remove(mhi_info, TYPE_MHI_READ_CH, buf, result->bytes_xferd); Loading Loading
drivers/char/diag/diag_usb.c +5 −0 Original line number Diff line number Diff line Loading @@ -520,6 +520,9 @@ int diag_usb_write(int id, unsigned char *buf, int len, int ctxt) usb_info = &diag_usb[id]; if (!atomic_read(&usb_info->connected)) return -ENOTCONN; if (len > usb_info->max_size) { DIAG_LOG(DIAG_DEBUG_MUX, "len: %d, max_size: %d\n", len, usb_info->max_size); Loading @@ -534,9 +537,11 @@ int diag_usb_write(int id, unsigned char *buf, int len, int ctxt) * trying to write more buffers than the max supported by * this particualar diag USB channel at any given instance, * or the previous write ptrs are stuck in the USB layer. * Remove the buffer entry from the usb buf table for this case. */ pr_err_ratelimited("diag: In %s, cannot retrieve USB write ptrs for USB channel %s\n", __func__, usb_info->name); diag_usb_buf_tbl_remove(usb_info, buf); return -ENOMEM; } Loading
drivers/char/diag/diagfwd_bridge.c +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #endif #include "diagfwd_mhi.h" #include "diag_dci.h" #include "diag_ipc_logging.h" #ifdef CONFIG_MHI_BUS #define diag_mdm_init diag_mhi_init Loading
drivers/char/diag/diagfwd_mhi.c +48 −21 Original line number Diff line number Diff line Loading @@ -83,7 +83,6 @@ struct diag_mhi_info diag_mhi[NUM_MHI_DEV] = { static int mhi_buf_tbl_add(struct diag_mhi_info *mhi_info, int type, void *buf, int len) { unsigned long flags; struct diag_mhi_buf_tbl_t *item; struct diag_mhi_ch_t *ch = NULL; Loading @@ -103,16 +102,14 @@ static int mhi_buf_tbl_add(struct diag_mhi_info *mhi_info, int type, return -EINVAL; } item = kzalloc(sizeof(struct diag_mhi_buf_tbl_t), GFP_KERNEL); item = kzalloc(sizeof(*item), GFP_ATOMIC); if (!item) return -ENOMEM; kmemleak_not_leak(item); spin_lock_irqsave(&ch->lock, flags); item->buf = buf; item->len = len; list_add_tail(&item->link, &ch->buf_tbl); spin_unlock_irqrestore(&ch->lock, flags); return 0; } Loading Loading @@ -166,7 +163,9 @@ static void mhi_buf_tbl_clear(struct diag_mhi_info *mhi_info) unsigned long flags; struct list_head *start, *temp; struct diag_mhi_buf_tbl_t *item = NULL; struct diag_mhi_buf_tbl_t *tp = NULL, *tp_temp = NULL; struct diag_mhi_ch_t *ch = NULL; unsigned char *buf; if (!mhi_info || !mhi_info->enabled) return; Loading @@ -180,9 +179,17 @@ static void mhi_buf_tbl_clear(struct diag_mhi_info *mhi_info) item = list_entry(start, struct diag_mhi_buf_tbl_t, link); list_del(&item->link); buf = item->buf; list_for_each_entry_safe(tp, tp_temp, &mhi_info->read_done_list, link) { if (tp->buf == buf) { list_del(&tp->link); kfree(tp); tp = NULL; } } diagmem_free(driver, item->buf, mhi_info->mempool); kfree(item); } spin_unlock_irqrestore(&ch->lock, flags); } Loading Loading @@ -348,9 +355,9 @@ static void mhi_read_done_work_fn(struct work_struct *work) do { if (!(atomic_read(&(mhi_info->read_ch.opened)))) break; spin_lock_irqsave(&mhi_info->lock, flags); spin_lock_irqsave(&mhi_info->read_ch.lock, flags); if (list_empty(&mhi_info->read_done_list)) { spin_unlock_irqrestore(&mhi_info->lock, flags); spin_unlock_irqrestore(&mhi_info->read_ch.lock, flags); break; } tp = list_first_entry(&mhi_info->read_done_list, Loading @@ -359,7 +366,7 @@ static void mhi_read_done_work_fn(struct work_struct *work) buf = tp->buf; len = tp->len; kfree(tp); spin_unlock_irqrestore(&mhi_info->lock, flags); spin_unlock_irqrestore(&mhi_info->read_ch.lock, flags); if (!buf) break; DIAG_LOG(DIAG_DEBUG_BRIDGE, Loading @@ -373,12 +380,15 @@ static void mhi_read_done_work_fn(struct work_struct *work) if ((atomic_read(&(mhi_info->read_ch.opened)))) { err = diag_remote_dev_read_done(mhi_info->dev_id, buf, len); if (err) if (err) { mhi_buf_tbl_remove(mhi_info, TYPE_MHI_READ_CH, buf, len); break; } } else { mhi_buf_tbl_remove(mhi_info, TYPE_MHI_READ_CH, buf, len); break; } } while (buf); } Loading @@ -400,22 +410,26 @@ static void mhi_read_work_fn(struct work_struct *work) do { if (!(atomic_read(&(read_ch->opened)))) break; spin_lock_irqsave(&read_ch->lock, flags); buf = diagmem_alloc(driver, DIAG_MDM_BUF_SIZE, mhi_info->mempool); if (!buf) { spin_unlock_irqrestore(&read_ch->lock, flags); if (!buf) break; } err = mhi_buf_tbl_add(mhi_info, TYPE_MHI_READ_CH, buf, DIAG_MDM_BUF_SIZE); if (err) if (err) { spin_unlock_irqrestore(&read_ch->lock, flags); goto fail; } DIAG_LOG(DIAG_DEBUG_BRIDGE, "queueing a read buf %pK, ch: %s\n", buf, mhi_info->name); spin_lock_irqsave(&read_ch->lock, flags); err = mhi_queue_transfer(mhi_info->mhi_dev, DMA_FROM_DEVICE, buf, DIAG_MDM_BUF_SIZE, mhi_flags); spin_unlock_irqrestore(&read_ch->lock, flags); Loading Loading @@ -475,12 +489,12 @@ static int mhi_write(int id, unsigned char *buf, int len, int ctxt) return -EIO; } spin_lock_irqsave(&ch->lock, flags); err = mhi_buf_tbl_add(&diag_mhi[id], TYPE_MHI_WRITE_CH, buf, len); if (err) goto fail; spin_lock_irqsave(&ch->lock, flags); err = mhi_queue_transfer(diag_mhi[id].mhi_dev, DMA_TO_DEVICE, buf, len, mhi_flags); spin_unlock_irqrestore(&ch->lock, flags); Loading Loading @@ -533,9 +547,11 @@ static void diag_mhi_read_cb(struct mhi_device *mhi_dev, struct mhi_result *result) { struct diag_mhi_info *mhi_info = NULL; struct diag_mhi_buf_tbl_t *tp; struct diag_mhi_buf_tbl_t *item = NULL; struct diag_mhi_buf_tbl_t *tp = NULL, *temp = NULL; unsigned long flags; void *buf = NULL; uint8_t queue_read = 0; if (!mhi_dev) return; Loading @@ -548,18 +564,29 @@ static void diag_mhi_read_cb(struct mhi_device *mhi_dev, return; if (atomic_read(&mhi_info->read_ch.opened) && result->transaction_status != -ENOTCONN) { spin_lock_irqsave(&mhi_info->read_ch.lock, flags); tp = kmalloc(sizeof(*tp), GFP_ATOMIC); if (!tp) { DIAG_LOG(DIAG_DEBUG_BRIDGE, "no mem for list\n"); spin_unlock_irqrestore(&mhi_info->read_ch.lock, flags); return; } list_for_each_entry_safe(item, temp, &mhi_info->read_ch.buf_tbl, link) { if (item->buf == buf) { tp->buf = buf; tp->len = result->bytes_xferd; spin_lock_irqsave(&mhi_info->lock, flags); list_add_tail(&tp->link, &mhi_info->read_done_list); spin_unlock_irqrestore(&mhi_info->lock, flags); queue_work(mhi_info->mhi_wq, &(mhi_info->read_done_work)); list_add_tail(&tp->link, &mhi_info->read_done_list); queue_read = 1; break; } } spin_unlock_irqrestore(&mhi_info->read_ch.lock, flags); if (queue_read) queue_work(mhi_info->mhi_wq, &(mhi_info->read_done_work)); } else { mhi_buf_tbl_remove(mhi_info, TYPE_MHI_READ_CH, buf, result->bytes_xferd); Loading