/** @brief function for IPC message reception Invokes cmd_handler for a command or recv_ipc_frames for IPC messages. @param mld the pointer to a mem_link_device instance */ static void ipc_rx_func(struct mem_link_device *mld) { struct sbd_link_device *sl = &mld->sbd_link_dev; while (1) { struct mst_buff *msb; u16 intr; msb = msb_dequeue(&mld->msb_rxq); if (!msb) break; intr = msb->snapshot.int2ap; if (cmd_valid(intr)) mld->cmd_handler(mld, int2cmd(intr)); if (sbd_active(sl)) recv_sbd_ipc_frames(mld); else recv_ipc_frames(mld, &msb->snapshot); msb_free(msb); } }
static void ipc_rx_func(struct mem_link_device *mld) { #ifdef CONFIG_LINK_DEVICE_WITH_SBD_ARCH struct sbd_link_device *sl = &mld->sbd_link_dev; #endif while (1) { struct mst_buff *msb; u16 intr; msb = msb_dequeue(&mld->msb_rxq); if (!msb) break; intr = msb->snapshot.int2ap; if (cmd_valid(intr)) mld->cmd_handler(mld, int2cmd(intr)); #ifdef CONFIG_LINK_DEVICE_WITH_SBD_ARCH if (sbd_active(sl)) recv_sbd_ipc_frames(mld, &msb->snapshot); else recv_ipc_frames(mld, &msb->snapshot); #else recv_ipc_frames(mld, &msb->snapshot); #endif #if 0 msb_queue_tail(&mld->msb_log, msb); #else msb_free(msb); #endif } }
/** @brief function for the @b send method in a link_device instance @param ld the pointer to a link_device instance @param iod the pointer to an io_device instance @param skb the pointer to an skb that will be transmitted @retval "> 0" the length of data transmitted if there is NO ERROR @retval "< 0" an error code */ static int mem_send(struct link_device *ld, struct io_device *iod, struct sk_buff *skb) { struct mem_link_device *mld = to_mem_link_device(ld); struct modem_ctl *mc = ld->mc; enum dev_format id = iod->format; u8 ch = iod->id; switch (id) { case IPC_FMT: case IPC_RAW: case IPC_RFS: if (likely(sipc5_ipc_ch(ch))) { if (unlikely(!ipc_active(mld))) return -EIO; if (iod->sbd_ipc) { if (likely(sbd_active(&mld->sbd_link_dev))) return xmit_ipc_to_rb(mld, ch, skb); else return -ENODEV; } else { BUG_ON(1); } } else { return xmit_udl(mld, iod, ch, skb); } break; case IPC_BOOT: case IPC_DUMP: if (sipc5_udl_ch(ch)) return xmit_udl(mld, iod, ch, skb); break; default: break; } mif_err("%s:%s->%s: ERR! Invalid IO device (format:%s id:%d)\n", ld->name, iod->name, mc->name, dev_str(id), ch); return -ENODEV; }
/** @brief take a snapshot of the current status of a memory interface Takes a snapshot of current @b @@dir memory status @param mld the pointer to a mem_link_device instance @param dir the direction of a communication (TX or RX) @return the pointer to a mem_snapshot instance */ struct mst_buff *mem_take_snapshot(struct mem_link_device *mld, enum direction dir) { struct mst_buff *msb = msb_alloc(); if (!msb) return NULL; #ifdef CONFIG_LINK_DEVICE_WITH_SBD_ARCH if (sbd_active(&mld->sbd_link_dev)) __take_sbd_status(mld, dir, &msb->snapshot); else __take_mem_status(mld, dir, &msb->snapshot); #else __take_mem_status(mld, dir, &msb->snapshot); #endif return msb; }
static int xmit_ipc(struct mem_link_device *mld, struct io_device *iod, enum sipc_ch_id ch, struct sk_buff *skb) { if (unlikely(!ipc_active(mld))) return -EIO; #ifdef CONFIG_LINK_DEVICE_WITH_SBD_ARCH if (iod->sbd_ipc) { if (likely(sbd_active(&mld->sbd_link_dev))) return xmit_ipc_to_rb(mld, ch, skb); else return -ENODEV; } else { return xmit_ipc_to_dev(mld, ch, skb); } #else return xmit_ipc_to_dev(mld, ch, skb); #endif }