📄 io_edgeport.c
字号:
} unicode_to_ascii(string, pStringDesc->wData, pStringDesc->bLength/2-1); kfree(pStringDesc); return strlen(string);}#if 0/************************************************************************ * * Get string descriptor from device * ************************************************************************/static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_descriptor **pRetDesc){ struct usb_string_descriptor StringDesc; struct usb_string_descriptor *pStringDesc; dbg("%s - USB String ID = %d", __FUNCTION__, Id ); if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, sizeof(StringDesc))) { return 0; } pStringDesc = kmalloc (StringDesc.bLength, GFP_KERNEL); if (!pStringDesc) { return -1; } if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc, StringDesc.bLength )) { kfree(pStringDesc); return -1; } *pRetDesc = pStringDesc; return 0;}#endifstatic void get_product_info(struct edgeport_serial *edge_serial){ struct edgeport_product_info *product_info = &edge_serial->product_info; memset (product_info, 0, sizeof(struct edgeport_product_info)); product_info->ProductId = (__u16)(le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ~ION_DEVICE_ID_80251_NETCHIP); product_info->NumPorts = edge_serial->manuf_descriptor.NumPorts; product_info->ProdInfoVer = 0; product_info->RomSize = edge_serial->manuf_descriptor.RomSize; product_info->RamSize = edge_serial->manuf_descriptor.RamSize; product_info->CpuRev = edge_serial->manuf_descriptor.CpuRev; product_info->BoardRev = edge_serial->manuf_descriptor.BoardRev; product_info->BootMajorVersion = edge_serial->boot_descriptor.MajorVersion; product_info->BootMinorVersion = edge_serial->boot_descriptor.MinorVersion; product_info->BootBuildNumber = edge_serial->boot_descriptor.BuildNumber; memcpy(product_info->ManufactureDescDate, edge_serial->manuf_descriptor.DescDate, sizeof(edge_serial->manuf_descriptor.DescDate)); // check if this is 2nd generation hardware if (le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ION_DEVICE_ID_80251_NETCHIP) { product_info->FirmwareMajorVersion = OperationalCodeImageVersion_GEN2.MajorVersion; product_info->FirmwareMinorVersion = OperationalCodeImageVersion_GEN2.MinorVersion; product_info->FirmwareBuildNumber = cpu_to_le16(OperationalCodeImageVersion_GEN2.BuildNumber); product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_80251; } else { product_info->FirmwareMajorVersion = OperationalCodeImageVersion_GEN1.MajorVersion; product_info->FirmwareMinorVersion = OperationalCodeImageVersion_GEN1.MinorVersion; product_info->FirmwareBuildNumber = cpu_to_le16(OperationalCodeImageVersion_GEN1.BuildNumber); product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_I930; } // Determine Product type and set appropriate flags switch (DEVICE_ID_FROM_USB_PRODUCT_ID(product_info->ProductId)) { case ION_DEVICE_ID_EDGEPORT_COMPATIBLE: case ION_DEVICE_ID_EDGEPORT_4T: case ION_DEVICE_ID_EDGEPORT_4: case ION_DEVICE_ID_EDGEPORT_2: case ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU: case ION_DEVICE_ID_EDGEPORT_8: case ION_DEVICE_ID_EDGEPORT_421: case ION_DEVICE_ID_EDGEPORT_21: case ION_DEVICE_ID_EDGEPORT_2_DIN: case ION_DEVICE_ID_EDGEPORT_4_DIN: case ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU: product_info->IsRS232 = 1; break; case ION_DEVICE_ID_EDGEPORT_2I: // Edgeport/2 RS422/RS485 product_info->IsRS422 = 1; product_info->IsRS485 = 1; break; case ION_DEVICE_ID_EDGEPORT_8I: // Edgeport/4 RS422 case ION_DEVICE_ID_EDGEPORT_4I: // Edgeport/4 RS422 product_info->IsRS422 = 1; break; } // Dump Product Info structure dbg("**Product Information:"); dbg(" ProductId %x", product_info->ProductId ); dbg(" NumPorts %d", product_info->NumPorts ); dbg(" ProdInfoVer %d", product_info->ProdInfoVer ); dbg(" IsServer %d", product_info->IsServer); dbg(" IsRS232 %d", product_info->IsRS232 ); dbg(" IsRS422 %d", product_info->IsRS422 ); dbg(" IsRS485 %d", product_info->IsRS485 ); dbg(" RomSize %d", product_info->RomSize ); dbg(" RamSize %d", product_info->RamSize ); dbg(" CpuRev %x", product_info->CpuRev ); dbg(" BoardRev %x", product_info->BoardRev); dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion, product_info->BootMinorVersion, le16_to_cpu(product_info->BootBuildNumber)); dbg(" FirmwareMajorVersion %d.%d.%d", product_info->FirmwareMajorVersion, product_info->FirmwareMinorVersion, le16_to_cpu(product_info->FirmwareBuildNumber)); dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0], product_info->ManufactureDescDate[1], product_info->ManufactureDescDate[2]+1900); dbg(" iDownloadFile 0x%x", product_info->iDownloadFile);}/************************************************************************//************************************************************************//* U S B C A L L B A C K F U N C T I O N S *//* U S B C A L L B A C K F U N C T I O N S *//************************************************************************//************************************************************************//***************************************************************************** * edge_interrupt_callback * this is the callback function for when we have received data on the * interrupt endpoint. *****************************************************************************/static void edge_interrupt_callback (struct urb *urb, struct pt_regs *regs){ struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context; struct edgeport_port *edge_port; struct usb_serial_port *port; unsigned char *data = urb->transfer_buffer; int length = urb->actual_length; int bytes_avail; int position; int txCredits; int portNumber; int result; dbg("%s", __FUNCTION__); switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } // process this interrupt-read even if there are no ports open if (length) { usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __FUNCTION__, length, data); if (length > 1) { bytes_avail = data[0] | (data[1] << 8); if (bytes_avail) { spin_lock(&edge_serial->es_lock); edge_serial->rxBytesAvail += bytes_avail; dbg("%s - bytes_avail=%d, rxBytesAvail=%d, read_in_progress=%d", __FUNCTION__, bytes_avail, edge_serial->rxBytesAvail, edge_serial->read_in_progress); if (edge_serial->rxBytesAvail > 0 && !edge_serial->read_in_progress) { dbg("%s - posting a read", __FUNCTION__); edge_serial->read_in_progress = TRUE; /* we have pending bytes on the bulk in pipe, send a request */ edge_serial->read_urb->dev = edge_serial->serial->dev; result = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC); if (result) { dev_err(&edge_serial->serial->dev->dev, "%s - usb_submit_urb(read bulk) failed with result = %d\n", __FUNCTION__, result); edge_serial->read_in_progress = FALSE; } } spin_unlock(&edge_serial->es_lock); } } /* grab the txcredits for the ports if available */ position = 2; portNumber = 0; while ((position < length) && (portNumber < edge_serial->serial->num_ports)) { txCredits = data[position] | (data[position+1] << 8); if (txCredits) { port = edge_serial->serial->port[portNumber]; edge_port = usb_get_serial_port_data(port); if (edge_port->open) { spin_lock(&edge_port->ep_lock); edge_port->txCredits += txCredits; spin_unlock(&edge_port->ep_lock); dbg("%s - txcredits for port%d = %d", __FUNCTION__, portNumber, edge_port->txCredits); /* tell the tty driver that something has changed */ if (edge_port->port->tty) tty_wakeup(edge_port->port->tty); // Since we have more credit, check if more data can be sent send_more_port_data(edge_serial, edge_port); } } position += 2; ++portNumber; } }exit: result = usb_submit_urb (urb, GFP_ATOMIC); if (result) { dev_err(&urb->dev->dev, "%s - Error %d submitting control urb\n", __FUNCTION__, result); }}/***************************************************************************** * edge_bulk_in_callback * this is the callback function for when we have received data on the * bulk in endpoint. *****************************************************************************/static void edge_bulk_in_callback (struct urb *urb, struct pt_regs *regs){ struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context; unsigned char *data = urb->transfer_buffer; int status; __u16 raw_data_length; dbg("%s", __FUNCTION__); if (urb->status) { dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); edge_serial->read_in_progress = FALSE; return; } if (urb->actual_length == 0) { dbg("%s - read bulk callback with no data", __FUNCTION__); edge_serial->read_in_progress = FALSE; return; } raw_data_length = urb->actual_length; usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __FUNCTION__, raw_data_length, data); spin_lock(&edge_serial->es_lock); /* decrement our rxBytes available by the number that we just got */ edge_serial->rxBytesAvail -= raw_data_length; dbg("%s - Received = %d, rxBytesAvail %d", __FUNCTION__, raw_data_length, edge_serial->rxBytesAvail); process_rcvd_data (edge_serial, data, urb->actual_length); /* check to see if there's any more data for us to read */ if (edge_serial->rxBytesAvail > 0) { dbg("%s - posting a read", __FUNCTION__); edge_serial->read_urb->dev = edge_serial->serial->dev; status = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC); if (status) { dev_err(&urb->dev->dev, "%s - usb_submit_urb(read bulk) failed, status = %d\n", __FUNCTION__, status); edge_serial->read_in_progress = FALSE; } } else { edge_serial->read_in_progress = FALSE; } spin_unlock(&edge_serial->es_lock);}/***************************************************************************** * edge_bulk_out_data_callback * this is the callback function for when we have finished sending serial data * on the bulk out endpoint. *****************************************************************************/static void edge_bulk_out_data_callback (struct urb *urb, struct pt_regs *regs){ struct edgeport_port *edge_port = (struct edgeport_port *)urb->context; struct tty_struct *tty; dbg("%s", __FUNCTION__); if (urb->status) { dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); } tty = edge_port->port->tty; if (tty && edge_port->open) { /* let the tty driver wakeup if it has a special write_wakeup function */ tty_wakeup(tty); } // Release the Write URB edge_port->write_in_progress = FALSE; // Check if more data needs to be sent send_more_port_data((struct edgeport_serial *)(usb_get_serial_data(edge_port->port->serial)), edge_port);}/***************************************************************************** * BulkOutCmdCallback * this is the callback function for when we have finished sending a command * on the bulk out endpoint. *****************************************************************************/static void edge_bulk_out_cmd_callback (struct urb *urb, struct pt_regs *regs){ struct edgeport_port *edge_port = (struct edgeport_port *)urb->context; struct tty_struct *tty; int status = urb->status; dbg("%s", __FUNCTION__); CmdUrbs--; dbg("%s - FREE URB %p (outstanding %d)", __FUNCTION__, urb, CmdUrbs); /* clean up the transfer buffer */ kfree(urb->transfer_buffer); /* Free the command urb */ usb_free_urb (urb); if (status) { dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, status); return; } /* Get pointer to tty */ tty = edge_port->port->tty; /* tell the tty driver that something has changed */ if (tty && edge_port->open) tty_wakeup(tty); /* we have completed the command */ edge_port->commandPending = FALSE; wake_up(&edge_port->wait_command);}/***************************************************************************** * Driver tty interface functions *****************************************************************************//***************************************************************************** * SerialOpen * this function is called by the tty driver when a port is opened * If successful, we return 0 * Otherwise we return a negative error number. *****************************************************************************/static int edge_open (struct usb_serial_port *port, struct file * filp){ struct edgeport_port *edge_port = usb_get_serial_port_data(port); struct usb_serial *serial; struct edgeport_serial *edge_serial; int response; dbg("%s - port %d", __FUNCTION__, port->number); if (edge_port == NULL) return -ENODEV; if (port->tty) port->tty->low_latency = low_latency; /* see if we've set up our endpoint info yet (can't set it up in edge_startup as the structures were not set up at that time.) */ serial = port->serial; edge_serial = usb_get_serial_data(serial); if (edge_serial == NULL) { return -ENODEV; } if (edge_serial->interrupt_in_buffer == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -