> Did you run checkpatch.pl, at least? That's what I get: > > ERROR: Missing Signed-off-by: line(s) > > total: 8 errors, 54 warnings, 727 lines checked > > Please fix and resubmit. Yes, I've run checkpatch.pl, but because I didn't need this line till now I ignored this error.
> > +/* MAX number of packets to put * > > + * into the device buffer, can * > > + * also be overridden */ > This should look like this: > /* > * MAX number of packets to put into the device buffer, can > * also be overridden. > */ > You get this wrong in several spots. Fixed. Signed-off-by: Maximilian Falkenstein <[email protected]> Index: kernel/2.6/drivers/net/can/slcan.c =================================================================== --- kernel/2.6/drivers/net/can/slcan.c (Revision 1054) +++ kernel/2.6/drivers/net/can/slcan.c (Arbeitskopie) @@ -11,6 +11,7 @@ * slip.c Authors : Laurence Culhane <[email protected]> * Fred N. van Kempen <[email protected]> * slcan.c Author : Oliver Hartkopp <[email protected]> + * Maximilian Falkenstein <[email protected]> * * Copyright (c) 2007-2009 Volkswagen Group Electronic Research * @@ -75,8 +76,10 @@ #include <socketcan/can.h> +#if 0 #include <socketcan/can/version.h> /* for RCSID. Removed by mkpatch script */ RCSID("$Id$"); +#endif static __initdata const char banner[] = KERN_INFO "slcan: serial line CAN interface driver\n"; @@ -132,12 +135,27 @@ module_param(maxdev, int, 0); MODULE_PARM_DESC(maxdev, "Maximum number of slcan interfaces"); -/* maximum rx buffer len: extended CAN frame with timestamp */ +/* + * MAX number of packets to put + * into the device buffer, can + * also be overridden + */ +static int maxack = 2; +module_param(maxack, int, 0); +MODULE_PARM_DESC(maxack, "Maximum number of packets to put into the \ + device buffer, be _VERY_ careful with this!"); + +/* maximum rx buffer len: extended CAN frame with timestamp in ASCII format */ #define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1) struct slcan { int magic; + /* We need some extra vars for binary mode! */ + int dnum; /* How many data bytes do we except to receive */ + int to_ack; /* How many packets have we put into the device buffer? */ + int rec_rcount; /* special rcount for recovery purposes */ + /* Various fields. */ struct tty_struct *tty; /* ptr to TTY structure */ struct net_device *dev; /* easy for intr handling */ @@ -158,7 +176,19 @@ unsigned long flags; /* Flag values/ mode etc */ #define SLF_INUSE 0 /* Channel in use */ #define SLF_ERROR 1 /* Parity, etc. error */ +#define SLF_BINENC 2 /* Do we use binary encapsulation? */ +#define SLF_EFRAME 3 /* Is the frame we are currently receiving extended */ +#define SLF_RESP 4 /* Is the next byte a response to a command */ +/* + * true, if we've paused the transmission of packets because + * the hardware hasn't answered (yet). + */ +#define SLF_PAUSED 5 + +#define SLF_LOST_SYNC 6 /* true, if we don't know what's going on... */ +#define SLF_FRAME_CANDIDAT 7 /* What we're receiving looks like a frame... */ + unsigned char leased; dev_t line; pid_t pid; @@ -166,7 +196,6 @@ static struct net_device **slcan_devs; - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) /* Netdevice get statistics request */ static struct net_device_stats *slc_get_stats(struct net_device *dev) @@ -210,6 +239,16 @@ * T12ABCDEF2AA55 : extended can_id 0x12ABCDEF, can_dlc 2, data 0xAA 0x55 * r1230 : can_id 0x123, can_dlc 0, no data, remote transmission request * + * NEW: We also have a binary encapsulation. It's very similar to the ASCII + * one, except that we don't user \r \n and don't convert to ASCII. The return + * value is also different! As the lib on controller doesn't differ between + * RTR and normal frame with 0 databytes, we don't differ between 'R' and 'T', + * too. + * + * Examples(Binary): + * t 0x01 0x23 0x00 : like t1230, can_id 0x123, can_dlc 0, no data + * T 0x12 0xAB 0xCD 0xEF 0x03 0xAA 0x55 : extended can_id 0x12ABCDEF, + * can_dlc 2,data 0xAA 0x55 */ /************************************************************************ @@ -245,50 +284,84 @@ unsigned long ultmp; char cmd = sl->rbuff[0]; - if ((cmd != 't') && (cmd != 'T') && (cmd != 'r') && (cmd != 'R')) - return; + if (!test_bit(SLF_BINENC, &sl->flags)) { + if ((cmd != 't') && (cmd != 'T') && (cmd != 'r') && (cmd != 'R')) + return; - if (cmd & 0x20) /* tiny chars 'r' 't' => standard frame format */ - dlc_pos = 4; /* dlc position tiiid */ - else - dlc_pos = 9; /* dlc position Tiiiiiiiid */ + if (cmd & 0x20) /* tiny chars 'r' 't' => standard frame format */ + dlc_pos = 4; /* dlc position tiiid */ + else + dlc_pos = 9; /* dlc position Tiiiiiiiid */ - if (!((sl->rbuff[dlc_pos] >= '0') && (sl->rbuff[dlc_pos] < '9'))) - return; + if (!((sl->rbuff[dlc_pos] >= '0') && (sl->rbuff[dlc_pos] < '9'))) + return; - cf.can_dlc = sl->rbuff[dlc_pos] - '0'; /* get can_dlc from ASCII val */ + cf.can_dlc = sl->rbuff[dlc_pos] - '0'; /* get can_dlc from ASCII val */ - sl->rbuff[dlc_pos] = 0; /* terminate can_id string */ + sl->rbuff[dlc_pos] = 0; /* terminate can_id string */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) - ultmp = simple_strtoul(sl->rbuff+1, NULL, 16); + ultmp = simple_strtoul(sl->rbuff+1, NULL, 16); #else - if (strict_strtoul(sl->rbuff+1, 16, &ultmp)) - return; + if (strict_strtoul(sl->rbuff + 1, 16, &ultmp)) + return; #endif - cf.can_id = ultmp; + cf.can_id = ultmp; - if (!(cmd & 0x20)) /* NO tiny chars => extended frame format */ - cf.can_id |= CAN_EFF_FLAG; + if (!(cmd & 0x20)) /* NO tiny chars => extended frame format */ + cf.can_id |= CAN_EFF_FLAG; - if ((cmd | 0x20) == 'r') /* RTR frame */ - cf.can_id |= CAN_RTR_FLAG; + if ((cmd | 0x20) == 'r') /* RTR frame */ + cf.can_id |= CAN_RTR_FLAG; - *(u64 *) (&cf.data) = 0; /* clear payload */ + *(u64 *) (&cf.data) = 0; /* clear payload */ - for (i = 0, dlc_pos++; i < cf.can_dlc; i++) { - - tmp = asc2nibble(sl->rbuff[dlc_pos++]); - if (tmp > 0x0F) + for (i = 0, dlc_pos++; i < cf.can_dlc; i++) { + tmp = asc2nibble(sl->rbuff[dlc_pos++]); + if (tmp > 0x0F) + return; + cf.data[i] = (tmp << 4); + tmp = asc2nibble(sl->rbuff[dlc_pos++]); + if (tmp > 0x0F) + return; + cf.data[i] |= tmp; + } + } else { + /* Binary */ + if (cmd == 't') { + /* Normal can frame */ + cf.can_id = (sl->rbuff[1] << 8) | sl->rbuff[2]; + cf.can_dlc = sl->rbuff[3]; + if (cf.can_dlc > 8) { + printk(KERN_WARNING "slcan: Frame with lenght above 8, \ + dropping!"); + stats->rx_dropped++; + stats->rx_errors++; + return; + } + for (i = 0; i < cf.can_dlc; i++) + cf.data[i] = sl->rbuff[4 + i]; + } else if (cmd == 'T') { + /* Extended can frame */ + cf.can_id = (sl->rbuff[1] << 24) | (sl->rbuff[2] << 16) + | (sl->rbuff[3] << 8) | sl->rbuff[4]; + cf.can_dlc = sl->rbuff[5]; + if (cf.can_dlc > 8) { + printk(KERN_WARNING "slcan: Frame with lenght above 8, \ + dropping!"); + stats->rx_dropped++; + stats->rx_errors++; + return; + } + for (i = 0; i < cf.can_dlc; i++) + cf.data[i] = sl->rbuff[6 + i]; + } else { + printk(KERN_WARNING "slcan: Got unknown can frame from device!"); + stats->rx_errors++; return; - cf.data[i] = (tmp << 4); - tmp = asc2nibble(sl->rbuff[dlc_pos++]); - if (tmp > 0x0F) - return; - cf.data[i] |= tmp; + } } - skb = dev_alloc_skb(sizeof(struct can_frame)); if (!skb) return; @@ -314,24 +387,211 @@ #else struct net_device_stats *stats = &sl->dev->stats; #endif + int i; + unsigned char nrbuff[SLC_MTU]; - if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */ - if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && - (sl->rcount > 4)) { + if (!test_bit(SLF_BINENC, &sl->flags)) { + /* ASCII */ + if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */ + if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && + (sl->rcount > 4)) { + slc_bump(sl); + } + sl->rcount = 0; + } else { + if (!test_bit(SLF_ERROR, &sl->flags)) { + if (sl->rcount < SLC_MTU) { + sl->rbuff[sl->rcount++] = s; + return; + } else { + stats->rx_over_errors++; + set_bit(SLF_ERROR, &sl->flags); + } + } + } + } else { + /* BINARY */ + if (test_bit(SLF_LOST_SYNC, &sl->flags)) { + /* OK, complicated things first(error recovery)... */ + sl->rbuff[sl->rec_rcount] = s; + sl->rec_rcount++; + + if (test_bit(SLF_FRAME_CANDIDAT, &sl->flags)) { + if (!test_bit(SLF_RESP, &sl->flags)) { + int offset = sl->rec_rcount - sl->rcount; + sl->rcount++; + if ((sl->rcount == 2 && !test_bit(SLF_EFRAME, &sl->flags)) + | (sl->rcount == 4 && test_bit(SLF_EFRAME, + &sl->flags))) { + /* We've recived the last bit of the CAN id */ + if (test_bit(SLF_EFRAME, &sl->flags) + && (((sl->rbuff[offset + 1] << 24) + | (sl->rbuff[offset + 2] << 16) + | (sl->rbuff[offset + 3] << 8) + | sl->rbuff[offset + 4]) > 0x1FFFFFFF) + | !test_bit(SLF_EFRAME, &sl->flags) + && ((sl->rbuff[offset + 1] << 8) + | sl->rbuff[offset + 2]) > 0x7FF) { + /* Invalid ID */ + goto invalid; + } + } else if ((sl->rcount == 5 && test_bit(SLF_EFRAME, + &sl->flags)) | ((sl->rcount == 3) && !test_bit( + SLF_EFRAME, &sl->flags))) { + if (s > 8) /* Invalid dlc */ + goto invalid; + else if (s == 0) { + goto rec_out_decaps; + } else { + sl->dnum = s; + return; + } + } else if (sl->dnum > 0) { + sl->dnum--; + if (sl->dnum == 0) { + /* Decaps */ + goto rec_out_decaps; + } + } + } else { + if (s & 0xf0) { + if (s != 0xf9) { + /*0xf9 means OK, everything different means error */ + printk(KERN_WARNING "%s: Command failed, retval: \ + %X\n", sl->dev->name, s); + stats->tx_errors++; + stats->tx_dropped++; + } + sl->to_ack--; + if (test_bit(SLF_PAUSED, &sl->flags) && (sl->to_ack + < maxack)) { + /* + * The device buffer is large enough for at least + * one more packet, so let's wake the quere + */ + clear_bit(SLF_PAUSED, &sl->flags); + netif_wake_queue(sl->dev); + } + clear_bit(SLF_RESP, &sl->flags); + sl->rcount = 0; + sl->rec_rcount = 0; + clear_bit(SLF_FRAME_CANDIDAT, &sl->flags); + clear_bit(SLF_LOST_SYNC, &sl->flags); + return; + } else + goto invalid; + } + } + if (sl->rec_rcount == SLC_MTU) { + printk(KERN_WARNING "%s: Buffer full, but still havn't \ + received a valid packet!\n", sl->dev->name); + sl->rcount = 0; + clear_bit(SLF_FRAME_CANDIDAT, &sl->flags); + } + if ((s == 't') | (s == 'T') | (s == 0xe0)) { + set_bit(SLF_FRAME_CANDIDAT, &sl->flags); + if (s == 't') + clear_bit(SLF_EFRAME, &sl->flags); + if (s == 'T') + set_bit(SLF_EFRAME, &sl->flags); + if (s == 0xe0) + set_bit(SLF_RESP, &sl->flags); + sl->rcount = 0; + } + return; + +invalid: clear_bit(SLF_FRAME_CANDIDAT, &sl->flags); + return; + +rec_out_decaps: + /* Modify buffer so that we can call slc_bump */ + for (i = 0; i <= sl->rcount; i++) + nrbuff[i] = sl->rbuff[sl->rec_rcount - sl->rcount - 1 + i]; + memcpy(sl->rbuff, nrbuff, sl->rcount + 1); slc_bump(sl); + sl->rcount = 0; + sl->rec_rcount = 0; + clear_bit(SLF_FRAME_CANDIDAT, &sl->flags); + clear_bit(SLF_LOST_SYNC, &sl->flags); + return; } - sl->rcount = 0; - } else { - if (!test_bit(SLF_ERROR, &sl->flags)) { - if (sl->rcount < SLC_MTU) { - sl->rbuff[sl->rcount++] = s; + + if (test_bit(SLF_RESP, &sl->flags)) { + if (s != 0xf9) { + /* 0xf9 means OK, everything different means error */ + printk(KERN_WARNING "%s: Command failed, retval: %X\n", + sl->dev->name, s); + stats->tx_errors++; + stats->tx_dropped++; + } + sl->to_ack--; + if (test_bit(SLF_PAUSED, &sl->flags) && (sl->to_ack < maxack)) { + /* + * The device buffer is large enough for at least one + * more packet, so let's wake the quere + */ + clear_bit(SLF_PAUSED, &sl->flags); + netif_wake_queue(sl->dev); + } + clear_bit(SLF_RESP, &sl->flags); + sl->rcount = 0; + return; + } + + if (sl->rcount == 0) { + /* + * What's coming next: a can frame, an extended can frame, or an + * ack/nack? + */ + if (s == 't') { + clear_bit(SLF_EFRAME, &sl->flags); + goto out_write; + } else if (s == 'T') { + set_bit(SLF_EFRAME, &sl->flags); + goto out_write; + } else if (s == 0xe0) { + /* ACK/NACK */ + set_bit(SLF_RESP, &sl->flags); + } else { + printk(KERN_WARNING "slcan (dev: %s): Unknown packet(head: \ + 0x%X), entering lost sync mode!\n", sl->dev->name, s); + stats->rx_errors++; + sl->rec_rcount = 0; + sl->rcount = 0; + sl->rec_rcount = 0; + set_bit(SLF_LOST_SYNC, &sl->flags); return; - } else { - stats->rx_over_errors++; - set_bit(SLF_ERROR, &sl->flags); } + } else if ((test_bit(SLF_EFRAME, &sl->flags) && sl->rcount == 5) + | ((!test_bit(SLF_EFRAME, &sl->flags)) && sl->rcount == 3)) { + /* Now we're receiving the payload lenght */ + if (s == 0) { + /* Oh, cool, a RTR; we can decapsulate it immediately */ + sl->rbuff[sl->rcount] = s; + goto out_decaps; + } + sl->dnum = s; + goto out_write; + } else { + /* More data */ + sl->rbuff[sl->rcount] = s; + sl->rcount++; + sl->dnum--; + if (sl->dnum == 0) + goto out_decaps; } } + return; + +out_write: + sl->rbuff[sl->rcount] = s; + sl->rcount++; + return; + +out_decaps: + slc_bump(sl); + sl->rcount = 0; + return; } /************************************************************************ @@ -349,41 +609,101 @@ int actual, idx, i; char cmd; - if (cf->can_id & CAN_RTR_FLAG) - cmd = 'R'; /* becomes 'r' in standard frame format */ - else - cmd = 'T'; /* becomes 't' in standard frame format */ + if (test_bit(SLF_BINENC, &sl->flags)) { + uint32_t id = cf->can_id & CAN_EFF_MASK; + uint8_t lof = 0; + if (cf->can_id & CAN_EFF_FLAG) { + sl->xbuff[0] = 'T'; /* Send */ + sl->xbuff[1] = (uint8_t)(id >> 24); + sl->xbuff[2] = (uint8_t)(id >> 16); + sl->xbuff[3] = (uint8_t)(id >> 8); + sl->xbuff[4] = (uint8_t) id; + lof = 4; + } else { + sl->xbuff[0] = 't'; /* Send */ + sl->xbuff[1] = (uint8_t)(id >> 8); + sl->xbuff[2] = (uint8_t) id; + lof = 2; + } + sl->xbuff[lof + 1] = cf->can_dlc; + /* Stringterm (Reordered for C90 compatibility) */ + sl->xbuff[lof + 2 + cf->can_dlc] = 0x00; - if (cf->can_id & CAN_EFF_FLAG) - sprintf(sl->xbuff, "%c%08X%d", cmd, - cf->can_id & CAN_EFF_MASK, cf->can_dlc); - else - sprintf(sl->xbuff, "%c%03X%d", cmd | 0x20, - cf->can_id & CAN_SFF_MASK, cf->can_dlc); + for (i = 0; i < cf->can_dlc; i++) + sl->xbuff[lof + 2 + i] = cf->data[i]; - idx = strlen(sl->xbuff); + /* + * We're going to put another packet into the device's buffer, + * let's tell the receiving side that we're sending something + * that's going to get a CMD_RESP + */ + sl->to_ack++; - for (i = 0; i < cf->can_dlc; i++) - sprintf(&sl->xbuff[idx + 2*i], "%02X", cf->data[i]); + /* + * Flow control: The device may be busy, but able to receive + * data (interrupt driven, at least in my firmware), but it + * can't handle an infinite amount of data, so we have to + * stop and wait for response after some packets... + */ + if (sl->to_ack >= maxack) + set_bit(SLF_PAUSED, &sl->flags); - DBG("ASCII frame = '%s'\n", sl->xbuff); + /* + * Order of next two lines is *very* important. + * When we are sending a little amount of data, + * the transfer may be completed inside driver.write() + * routine, because it's running with interrupts enabled. + * In this case we *never* got WRITE_WAKEUP event, + * if we did not request it before write operation. + * 14 Oct 1994 Dmitry Gorodchanin. + */ + sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) + actual = sl->tty->driver->write(sl->tty, sl->xbuff, (cf->can_id & + CAN_EFF_FLAG ? 6 : 4)+cf->can_dlc); +#else + actual = sl->tty->ops->write(sl->tty, sl->xbuff, (cf->can_id + & CAN_EFF_FLAG ? 6 : 4) + cf->can_dlc); +#endif - strcat(sl->xbuff, "\r"); /* add terminating character */ + } else { + if (cf->can_id & CAN_RTR_FLAG) + cmd = 'R'; /* becomes 'r' in standard frame format */ + else + cmd = 'T'; /* becomes 't' in standard frame format */ - /* Order of next two lines is *very* important. - * When we are sending a little amount of data, - * the transfer may be completed inside driver.write() - * routine, because it's running with interrupts enabled. - * In this case we *never* got WRITE_WAKEUP event, - * if we did not request it before write operation. - * 14 Oct 1994 Dmitry Gorodchanin. - */ - sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); + if (cf->can_id & CAN_EFF_FLAG) + sprintf(sl->xbuff, "%c%08X%d", cmd, cf->can_id & CAN_EFF_MASK, + cf->can_dlc); + else + sprintf(sl->xbuff, "%c%03X%d", cmd | 0x20, cf->can_id + & CAN_SFF_MASK, cf->can_dlc); + + idx = strlen(sl->xbuff); + + for (i = 0; i < cf->can_dlc; i++) + sprintf(&sl->xbuff[idx + 2 * i], "%02X", cf->data[i]); + + DBG("ASCII frame = '%s'\n", sl->xbuff); + + strcat(sl->xbuff, "\r"); /* add terminating character */ + + /* + * Order of next two lines is *very* important. + * When we are sending a little amount of data, + * the transfer may be completed inside driver.write() + * routine, because it's running with interrupts enabled. + * In this case we *never* got WRITE_WAKEUP event, + * if we did not request it before write operation. + * 14 Oct 1994 Dmitry Gorodchanin. + */ + sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) - actual = sl->tty->driver->write(sl->tty, sl->xbuff, strlen(sl->xbuff)); + actual = sl->tty->driver->write(sl->tty, sl->xbuff, strlen(sl->xbuff)); #else - actual = sl->tty->ops->write(sl->tty, sl->xbuff, strlen(sl->xbuff)); + actual = sl->tty->ops->write(sl->tty, sl->xbuff, strlen(sl->xbuff)); #endif + } #ifdef SLC_CHECK_TRANSMIT sl->dev->trans_start = jiffies; #endif @@ -415,7 +735,14 @@ * transmission of another packet */ stats->tx_packets++; tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - netif_wake_queue(sl->dev); + + /* + * Maybe the device isn't ready, lets check before + * we try to send the next packet + */ + if (!(test_bit(SLF_BINENC, &sl->flags) && test_bit(SLF_PAUSED, + &sl->flags))) + netif_wake_queue(sl->dev); return; } @@ -462,7 +789,6 @@ spin_unlock(&sl->lock); } - /****************************************** * Routines looking at netdevice side. ******************************************/ @@ -496,7 +822,6 @@ return 0; } - /* Netdevice UP -> DOWN routine */ static int slc_close(struct net_device *dev) { @@ -523,7 +848,7 @@ if (sl->tty == NULL) return -ENODEV; - sl->flags &= (1 << SLF_INUSE); + sl->flags &= (1 << SLF_INUSE) | (1 << SLF_BINENC); netif_start_queue(dev); return 0; } @@ -591,7 +916,6 @@ * be re-entered while running but other ldisc functions may be called * in parallel */ - static void slcan_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { @@ -643,7 +967,6 @@ } } - /* Find a free SLCAN channel, and link in this `tty' line. */ static struct slcan *slc_alloc(dev_t line) { @@ -737,6 +1060,7 @@ /* Initialize channel control data */ sl->magic = SLCAN_MAGIC; sl->dev = dev; + sl->to_ack = 0; spin_lock_init(&sl->lock); slcan_devs[i] = dev; @@ -752,7 +1076,6 @@ * * Called in process context serialized from other ldisc calls. */ - static int slcan_open(struct tty_struct *tty) { struct slcan *sl; @@ -885,6 +1208,21 @@ return -EINVAL; switch (cmd) { + case SIOCGIFENCAP: + /* Do we use binary encapsulation? */ + return test_bit(SLF_BINENC, &sl->flags); + case SIOCSIFENCAP: + /* Let's modify our encapsulation! */ + if (arg > 0) { + set_bit(SLF_BINENC, &sl->flags); + printk(KERN_INFO "slcan: Now using binary encapsulation on device \ + %s!", sl->dev->name); + } else { + clear_bit(SLF_BINENC, &sl->flags); + printk(KERN_INFO "slcan: Now using ASCII encapsulation on device \ + %s!", sl->dev->name); + } + return 0; case SIOCGIFNAME: tmp = strlen(sl->dev->name) + 1; if (copy_to_user((void __user *)arg, sl->dev->name, tmp)) @@ -938,6 +1276,9 @@ if (maxdev < 4) maxdev = 4; /* Sanity */ + if (maxack < 1) + maxack = 1; /* Dito */ + printk(banner); printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev); @@ -1019,3 +1360,4 @@ module_init(slcan_init); module_exit(slcan_exit); + Index: can-utils/slcan_attach.c =================================================================== --- can-utils/slcan_attach.c (Revision 1054) +++ can-utils/slcan_attach.c (Arbeitskopie) @@ -45,14 +45,19 @@ * */ -#include <stdio.h> +#include <termios.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> -#include <fcntl.h> -#include <unistd.h> +#include <stdio.h> #include <getopt.h> #include <sys/ioctl.h> +#include <sys/select.h> +#include <sys/file.h> +#define BUFFERSIZE 20 #define LDISC_N_SLCAN 17 /* default slcan line discipline since Kernel 2.6.25 */ void print_usage(char *prg) @@ -64,6 +69,7 @@ fprintf(stderr, " -b <btr> (set bit time register value)\n"); fprintf(stderr, " -d (only detach line discipline)\n"); fprintf(stderr, " -w (attach - wait for keypess - detach)\n"); + fprintf(stderr, " -B (use binary mode)\n"); fprintf(stderr, "\nExamples:\n"); fprintf(stderr, "slcan_attach -w -o -s6 -c /dev/ttyS1\n"); fprintf(stderr, "slcan_attach /dev/ttyS1\n"); @@ -80,18 +86,23 @@ int waitkey = 0; int send_open = 0; int send_close = 0; + int binary = 0; char *speed = NULL; char *btr = NULL; char buf[10]; char *tty; int opt; - while ((opt = getopt(argc, argv, "l:dwocs:b:?")) != -1) { + while ((opt = getopt(argc, argv, "l:dwBocs:b:?")) != -1) { switch (opt) { case 'l': fprintf(stderr, "Ignored option '-l'\n"); break; + case 'B': + binary = 1; + break; + case 'd': detach = 1; break; @@ -157,6 +168,10 @@ if (ioctl (fd, TIOCSETD, &ldisc) < 0) { perror("ioctl"); exit(1); + } else { + if (binary) + if (ioctl(fd, SIOCSIFENCAP, 1) != 0) + perror("ioctl2"); } } _______________________________________________ Socketcan-core mailing list [email protected] https://lists.berlios.de/mailman/listinfo/socketcan-core
