int command(isdn_ctrl *cmd) { int card; card = get_card_from_id(cmd->driver); if(!IS_VALID_CARD(card)) { pr_debug("Invalid param: %d is not a valid card id\n", card); return -ENODEV; } /* * Dispatch the command */ switch(cmd->command) { case ISDN_CMD_IOCTL: { unsigned long cmdptr; scs_ioctl ioc; memcpy(&cmdptr, cmd->parm.num, sizeof(unsigned long)); if (copy_from_user(&ioc, (scs_ioctl __user *)cmdptr, sizeof(scs_ioctl))) { pr_debug("%s: Failed to verify user space 0x%lx\n", sc_adapter[card]->devicename, cmdptr); return -EFAULT; } return sc_ioctl(card, &ioc); } case ISDN_CMD_DIAL: return dial(card, cmd->arg, cmd->parm.setup); case ISDN_CMD_HANGUP: return hangup(card, cmd->arg); case ISDN_CMD_ACCEPTD: return answer(card, cmd->arg); case ISDN_CMD_ACCEPTB: return acceptb(card, cmd->arg); case ISDN_CMD_CLREAZ: return clreaz(card, cmd->arg); case ISDN_CMD_SETEAZ: return seteaz(card, cmd->arg, cmd->parm.num); case ISDN_CMD_SETL2: return setl2(card, cmd->arg); case ISDN_CMD_SETL3: return setl3(card, cmd->arg); default: return -EINVAL; } return 0; }
int sndpkt(int devId, int channel, struct sk_buff *data) { LLData ReqLnkWrite; int status; int card; unsigned long len; card = get_card_from_id(devId); if(!IS_VALID_CARD(card)) { pr_debug("invalid param: %d is not a valid card id\n", card); return -ENODEV; } pr_debug("%s: sndpkt: frst = 0x%x nxt = %d f = %d n = %d\n", adapter[card]->devicename, adapter[card]->channel[channel].first_sendbuf, adapter[card]->channel[channel].next_sendbuf, adapter[card]->channel[channel].free_sendbufs, adapter[card]->channel[channel].num_sendbufs); if(!adapter[card]->channel[channel].free_sendbufs) { pr_debug("%s: out of TX buffers\n", adapter[card]->devicename); return -EINVAL; } if(data->len > BUFFER_SIZE) { pr_debug("%s: data overflows buffer size (data > buffer)\n", adapter[card]->devicename); return -EINVAL; } ReqLnkWrite.buff_offset = adapter[card]->channel[channel].next_sendbuf * BUFFER_SIZE + adapter[card]->channel[channel].first_sendbuf; ReqLnkWrite.msg_len = data->len; /* sk_buff size */ pr_debug("%s: writing %d bytes to buffer offset 0x%x\n", adapter[card]->devicename, ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset); memcpy_toshmem(card, (char *)ReqLnkWrite.buff_offset, data->data, ReqLnkWrite.msg_len); /* * sendmessage */ pr_debug("%s: sndpkt size=%d, buf_offset=0x%x buf_indx=%d\n", adapter[card]->devicename, ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset, adapter[card]->channel[channel].next_sendbuf); status = sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkWrite, channel+1, sizeof(LLData), (unsigned int*)&ReqLnkWrite); len = data->len; if(status) { pr_debug("%s: failed to send packet, status = %d\n", adapter[card]->devicename, status); return -1; } else { adapter[card]->channel[channel].free_sendbufs--; adapter[card]->channel[channel].next_sendbuf = ++adapter[card]->channel[channel].next_sendbuf == adapter[card]->channel[channel].num_sendbufs ? 0 : adapter[card]->channel[channel].next_sendbuf; pr_debug("%s: packet sent successfully\n", adapter[card]->devicename); dev_kfree_skb(data); indicate_status(card,ISDN_STAT_BSENT,channel, (char *)&len); } return len; }