in serial/icom.c [163:276]
static int get_port_memory(struct icom_port *icom_port)
{
int index;
unsigned long stgAddr;
unsigned long startStgAddr;
unsigned long offset;
struct pci_dev *dev = icom_port->adapter->pci_dev;
icom_port->xmit_buf =
dma_alloc_coherent(&dev->dev, 4096, &icom_port->xmit_buf_pci,
GFP_KERNEL);
if (!icom_port->xmit_buf) {
dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
return -ENOMEM;
}
trace(icom_port, "GET_PORT_MEM",
(unsigned long) icom_port->xmit_buf);
icom_port->recv_buf =
dma_alloc_coherent(&dev->dev, 4096, &icom_port->recv_buf_pci,
GFP_KERNEL);
if (!icom_port->recv_buf) {
dev_err(&dev->dev, "Can not allocate Receive buffer\n");
free_port_memory(icom_port);
return -ENOMEM;
}
trace(icom_port, "GET_PORT_MEM",
(unsigned long) icom_port->recv_buf);
icom_port->statStg =
dma_alloc_coherent(&dev->dev, 4096, &icom_port->statStg_pci,
GFP_KERNEL);
if (!icom_port->statStg) {
dev_err(&dev->dev, "Can not allocate Status buffer\n");
free_port_memory(icom_port);
return -ENOMEM;
}
trace(icom_port, "GET_PORT_MEM",
(unsigned long) icom_port->statStg);
icom_port->xmitRestart =
dma_alloc_coherent(&dev->dev, 4096, &icom_port->xmitRestart_pci,
GFP_KERNEL);
if (!icom_port->xmitRestart) {
dev_err(&dev->dev,
"Can not allocate xmit Restart buffer\n");
free_port_memory(icom_port);
return -ENOMEM;
}
/* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
indicates that frames are to be transmitted
*/
stgAddr = (unsigned long) icom_port->statStg;
for (index = 0; index < NUM_XBUFFS; index++) {
trace(icom_port, "FOD_ADDR", stgAddr);
stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
if (index < (NUM_XBUFFS - 1)) {
memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
icom_port->statStg->xmit[index].leLengthASD =
(unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
trace(icom_port, "FOD_ADDR", stgAddr);
trace(icom_port, "FOD_XBUFF",
(unsigned long) icom_port->xmit_buf);
icom_port->statStg->xmit[index].leBuffer =
cpu_to_le32(icom_port->xmit_buf_pci);
} else if (index == (NUM_XBUFFS - 1)) {
memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
icom_port->statStg->xmit[index].leLengthASD =
(unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
trace(icom_port, "FOD_XBUFF",
(unsigned long) icom_port->xmit_buf);
icom_port->statStg->xmit[index].leBuffer =
cpu_to_le32(icom_port->xmit_buf_pci);
} else {
memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
}
}
/* FIDs */
startStgAddr = stgAddr;
/* fill in every entry, even if no buffer */
for (index = 0; index < NUM_RBUFFS; index++) {
trace(icom_port, "FID_ADDR", stgAddr);
stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
icom_port->statStg->rcv[index].leLength = 0;
icom_port->statStg->rcv[index].WorkingLength =
(unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
if (index < (NUM_RBUFFS - 1) ) {
offset = stgAddr - (unsigned long) icom_port->statStg;
icom_port->statStg->rcv[index].leNext =
cpu_to_le32(icom_port-> statStg_pci + offset);
trace(icom_port, "FID_RBUFF",
(unsigned long) icom_port->recv_buf);
icom_port->statStg->rcv[index].leBuffer =
cpu_to_le32(icom_port->recv_buf_pci);
} else if (index == (NUM_RBUFFS -1) ) {
offset = startStgAddr - (unsigned long) icom_port->statStg;
icom_port->statStg->rcv[index].leNext =
cpu_to_le32(icom_port-> statStg_pci + offset);
trace(icom_port, "FID_RBUFF",
(unsigned long) icom_port->recv_buf + 2048);
icom_port->statStg->rcv[index].leBuffer =
cpu_to_le32(icom_port->recv_buf_pci + 2048);
} else {
icom_port->statStg->rcv[index].leNext = 0;
icom_port->statStg->rcv[index].leBuffer = 0;
}
}
return 0;
}