/* * GeneSys GL620USB-A (www.genesyslogic.com.tw) * * ... should partially interop with the Win32 driver for this hardware. * The GeneSys docs imply there's some NDIS issue motivating this framing. * * Some info from GeneSys: * - GL620USB-A is full duplex; GL620USB is only half duplex for bulk. * (Some cables, like the BAFO-100c, use the half duplex version.) * - For the full duplex model, the low bit of the version code says * which side is which ("left/right"). * - For the half duplex type, a control/interrupt handshake settles * the transfer direction. (That's disabled here, partially coded.) * A control URB would block until other side writes an interrupt. * * Original code from Jiun-Jie Huang <huangjj@genesyslogic.com.tw> * and merged into "usbnet" by Stanislav Brabec <utx@penguin.cz>.
*/
// control msg write command #define GENELINK_CONNECT_WRITE 0xF0 // interrupt pipe index #define GENELINK_INTERRUPT_PIPE 0x03 // interrupt read buffer size #define INTERRUPT_BUFSIZE 0x08 // interrupt pipe interval value #define GENELINK_INTERRUPT_INTERVAL 0x10 // max transmit packet number per transmit #define GL_MAX_TRANSMIT_PACKETS 32 // max packet length #define GL_MAX_PACKET_LEN 1514 // max receive buffer size #define GL_RCV_BUF_SIZE \
(((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4)
/* This check is no longer done by usbnet */ if (skb->len < dev->net->hard_header_len) return 0;
header = (struct gl_header *) skb->data;
// get the packet count of the received skb
count = le32_to_cpu(header->packet_count); if (count > GL_MAX_TRANSMIT_PACKETS) {
netdev_dbg(dev->net, "genelink: invalid received packet count %u\n",
count); return 0;
}
// set the current packet pointer to the first packet
packet = &header->packets;
// decrement the length for the packet count size 4 bytes
skb_pull(skb, 4);
while (count > 1) { // get the packet length
size = le32_to_cpu(packet->packet_length);
// this may be a broken packet if (size > GL_MAX_PACKET_LEN) {
netdev_dbg(dev->net, "genelink: invalid rx length %d\n",
size); return 0;
}
// allocate the skb for the individual packet
gl_skb = alloc_skb(size, GFP_ATOMIC); if (gl_skb) {
// copy the packet data to the new skb
skb_put_data(gl_skb, packet->packet_data, size);
usbnet_skb_return(dev, gl_skb);
}
// advance to the next packet
packet = (struct gl_packet *)&packet->packet_data[size];
count--;
// shift the data pointer to the next gl_packet
skb_pull(skb, size + 4);
}
// skip the packet length field 4 bytes
skb_pull(skb, 4);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.