From: Grosjean Stephane <s.grosjean@peak-system.com>
To: Sebastian Haas <dev@sebastianhaas.info>
Cc: Oliver Hartkopp <socketcan@hartkopp.net>,
Linux CAN mailing list <linux-can@vger.kernel.org>
Subject: Re: [PATCH] Add support for PEAK System PCAN-USB Pro adapter
Date: Mon, 26 Dec 2011 11:55:34 +0100 [thread overview]
Message-ID: <4EF852A6.3050201@peak-system.com> (raw)
In-Reply-To: <4EF4DD47.3040900@sebastianhaas.info>
Hello Sebastian,
Le 23/12/2011 20:57, Sebastian Haas a écrit :
> Hi Stéphane,
>
> just some minor annotations.
>
> Cheers and Merry Christmas,
> Sebastian
>
> Am 22.12.2011 14:14, schrieb Stephane Grosjean:
>> +static int pcan_usb_pro_sizeof_rec(u8 data_type)
>> +{
>> + switch (data_type) {
>> + case PCAN_USBPRO_RXMSG8:
>> + return sizeof(struct pcan_usb_pro_rxmsg);
>> + case PCAN_USBPRO_RXMSG4:
>> + return sizeof(struct pcan_usb_pro_rxmsg) - 4;
>> + case PCAN_USBPRO_RXMSG0:
>> + case PCAN_USBPRO_RXRTR:
>> + return sizeof(struct pcan_usb_pro_rxmsg) - 8;
>> + case PCAN_USBPRO_RXSTATUS:
>> + return sizeof(struct pcan_usb_pro_rxstatus);
> ...
> I wonder if it is possible to use some kind of a table here to improve
> readability and reduce code.
> ...
Yes it is... You all are right: I changed that ugly function with
something like that:
/* record size array */
static u16 pcan_usb_pro_sizeof_rec[256] = {
[PCAN_USBPRO_RXMSG8] = sizeof(struct pcan_usb_pro_rxmsg),
[PCAN_USBPRO_RXMSG4] = sizeof(struct pcan_usb_pro_rxmsg) - 4,
[PCAN_USBPRO_RXMSG0] = sizeof(struct pcan_usb_pro_rxmsg) - 8,
[PCAN_USBPRO_RXRTR] = sizeof(struct pcan_usb_pro_rxmsg) - 8,
[PCAN_USBPRO_RXSTATUS] = sizeof(struct pcan_usb_pro_rxstatus),
...
and changed the (2) function calls from:
rec_len = pcan_usb_pro_sizeof_rec(x);
if (rec_len <= 0) {
to:
rec_len = pcan_usb_pro_sizeof_rec[x];
if (!rec_len) {
(knowing that "x" is always a BYTE value)
>> + case PCAN_USBPRO_SETLED:
>> + return sizeof(struct pcan_usb_pro_setled);
>> + default:
>> + pr_info("%s: %s(%d): unsupported data type\n",
>> + PCAN_USB_DRIVER_NAME, __func__, data_type);
>> + break;
>> + }
>> +
>> + return -1;
>> +}
>> +static int pcan_usb_pro_set_bittiming(struct peak_usb_device *dev,
>> + struct can_bittiming *bt)
>> +{
>> + struct pcan_usb_pro_msg um;
>> + u8 tmp[32];
>> + u32 ccbt;
>> +
>> + ccbt = (dev->can.ctrlmode& CAN_CTRLMODE_3_SAMPLES) ? 0x00800000
>> : 0;
>> + ccbt |= (bt->sjw - 1)<< 24;
>> + ccbt |= (bt->phase_seg2 - 1)<< 20;
>> + ccbt |= (bt->prop_seg + bt->phase_seg1 - 1)<< 16; /* = tseg1 */
>> + ccbt |= bt->brp - 1;
> Does the PCAN-USB uses a NXP LPC21xx controller?
I suppose you ask for the "PCAN-USB Pro" adapter, right? Yes it does.
>> +
>> + netdev_dbg(dev->netdev, "ccbt=0x%08x\n", ccbt);
>> +
>> + pcan_usb_pro_msg_init_empty(&um, tmp, sizeof(tmp));
>> + pcan_usb_pro_add_rec(&um, PCAN_USBPRO_SETBTR, dev->ctrl_idx, ccbt);
>> +
>> + return pcan_usb_pro_send_cmd(dev,&um);
>> +}
>> +/*
>> + * callback for bulk IN urb
>> + */
>> +static int pcan_usb_pro_decode_buf(struct peak_usb_device *dev,
>> struct urb *urb)
>> +{
>> + struct pcan_usb_pro_interface *usb_if = pcan_usb_pro_dev_if(dev);
>> + struct net_device *netdev = dev->netdev;
>> + struct pcan_usb_pro_msg usb_msg;
>> + u8 *rec_ptr, *msg_end;
>> + u16 rec_cnt;
>> + int err = 0;
>> +
>> + rec_ptr = pcan_usb_pro_msg_init(&usb_msg, urb->transfer_buffer,
>> + urb->actual_length);
>> + if (!rec_ptr) {
>> + netdev_err(netdev, "bad msg hdr len %d\n", urb->actual_length);
>> + return -EINVAL;
>> + }
>> +
>> + /* loop reading all the records from the incoming message */
>> + msg_end = urb->transfer_buffer + urb->actual_length;
>> + rec_cnt = le16_to_cpu(*usb_msg.u.rec_cnt_rd);
>> + for (; rec_cnt> 0; rec_cnt--) {
>> + union pcan_usb_pro_rec *pr = (union pcan_usb_pro_rec *)rec_ptr;
>> + int sizeof_rec = pcan_usb_pro_sizeof_rec(pr->data_type);
>> +
>> + if (sizeof_rec<= 0) {
>> + netdev_err(netdev,
>> + "got unsupported rec in usb msg:\n");
>> + err = -ENOTSUPP;
>> + break;
>> + }
>> +
>> + /* check if the record goes out of current packet */
>> + if (rec_ptr + sizeof_rec> msg_end) {
>> + netdev_err(netdev,
>> + "got frag rec: should inc usb rx buf size\n");
>> + err = -EBADMSG;
>> + break;
>> + }
>> +
>> + switch (pr->data_type) {
>> + case PCAN_USBPRO_RXMSG8:
>> + case PCAN_USBPRO_RXMSG4:
>> + case PCAN_USBPRO_RXMSG0:
>> + case PCAN_USBPRO_RXRTR:
>> + err = pcan_usb_pro_handle_canmsg(usb_if,&pr->rx_msg);
>> + if (err< 0)
>> + goto fail;
>> + break;
>> +
>> + case PCAN_USBPRO_RXSTATUS:
>> + err = pcan_usb_pro_handle_error(usb_if,&pr->rx_status);
>> + if (err< 0)
>> + goto fail;
>> + break;
>> +
>> + case PCAN_USBPRO_RXTS:
>> + err = pcan_usb_pro_handle_ts(usb_if,&pr->rx_ts);
> No handling in error case, is that right?
to be coherent, all the "pcan_usb_pro_handle_xxx()" functions return an
int... But this one always returns 0... So, I changed it into "void
pcan_usb_pro_handle_ts()" now.
>> + break;
>> +
>> + default:
>> + netdev_err(netdev,
>> + "unhandled rec type 0x%02x (%d): ignored\n",
>> + pr->data_type, pr->data_type);
>> + break;
>> + }
>> +
>> + rec_ptr += sizeof_rec;
>> + }
>> +
>> +fail:
>> + if (err)
>> + dump_mem("received msg",
>> + urb->transfer_buffer, urb->actual_length);
>> +
>> + return err;
>> +}
>> +
>> +static int pcan_usb_pro_encode_msg(struct peak_usb_device *dev,
>> + struct sk_buff *skb, u8 *obuf, size_t *size)
>> +{
>> + struct can_frame *cf = (struct can_frame *)skb->data;
>> + u8 data_type, len, flags;
>> + struct pcan_usb_pro_msg usb_msg;
>> + int err = 0;
>> +
>> + pcan_usb_pro_msg_init_empty(&usb_msg, obuf, *size);
>> +
>> + if ((cf->can_id& CAN_RTR_FLAG) || (cf->can_dlc == 0))
>> + data_type = PCAN_USBPRO_TXMSG0;
>> +
> Remove empty line.
Ok.
>> + else if (cf->can_dlc<= 4)
>> + data_type = PCAN_USBPRO_TXMSG4;
>> + else
>> + data_type = PCAN_USBPRO_TXMSG8;
>> +
>> + len = (dev->ctrl_idx<< 4) | (cf->can_dlc& 0x0f);
>> +
>> + flags = 0;
>> + if (cf->can_id& CAN_EFF_FLAG)
>> + flags |= 0x02;
>> + if (cf->can_id& CAN_RTR_FLAG)
>> + flags |= 0x01;
>> +
>> + err = pcan_usb_pro_add_rec(&usb_msg, data_type, 0, flags, len,
>> + cf->can_id, cf->data);
> \err\ is not checked.
Yes you're right, and it does not need to be. So I removed the "err"
local variable from the function.
>> +
>> + *size = usb_msg.rec_buffer_len;
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * called when probing to initialize a device object.
>> + */
>> +static int pcan_usb_pro_init(struct peak_usb_device *dev)
>> +{
>> + struct pcan_usb_pro_interface *usb_if;
>> + struct pcan_usb_pro_device *pdev = (struct pcan_usb_pro_device
>> *)dev;
>> +
>> + /* do this for 1st channel only */
>> + if (!dev->prev_siblings) {
>> + struct pcan_usb_pro_fwinfo fi;
>> + struct pcan_usb_pro_blinfo bi;
>> +
>> + /* tell the device the can driver is running */
>> + pcan_usb_pro_drv_loaded(dev, 1);
>> +
>> + if (pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
>> + PCAN_USBPRO_INFO_FIRMWARE,&fi, sizeof(fi))>= 0)
>> + netdev_info(dev->netdev,
>> + "%s fw v%d.%d.%d (%02d/%02d/%02d) fw 0x%08x\n",
>> + pcan_usb_pro.name,
>> + fi.version[0], fi.version[1], fi.version[2],
>> + fi.day, fi.month, fi.year, fi.fw_type);
>> +
>> + if (pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
>> + PCAN_USBPRO_INFO_BOOTLOADER,&bi, sizeof(bi))>= 0) {
>> + netdev_info(dev->netdev,
>> + "bootloader v%d.%d.%d (%02d/%02d/%02d)\n",
>> + bi.version[0], bi.version[1], bi.version[2],
>> + bi.day, bi.month, bi.year);
>> +
>> + netdev_info(dev->netdev,
>> + "serial %08X.%08X hw 0x%08x rev 0x%08x\n",
>> + bi.serial_num_hi, bi.serial_num_lo,
>> + bi.hw_type, bi.hw_rev);
>> +
>> + dev->device_rev = (u8)bi.hw_rev;
>> + }
>> +
>> + usb_if = kzalloc(sizeof(struct pcan_usb_pro_interface),
>> + GFP_KERNEL);
>> + if (!usb_if)
>> + return -ENOMEM;
> Is it necessary to call pcan_usb_pro_drv_loaded(dev, 0) here?
I think you're right too... But I preferred to move the (dev, 1) call
from the beginning of the block to its end (immediately after
cm_ignore_count = 5).
>> +
>> + /* number of ts msgs to ignore before taking one into
>> account */
>> + usb_if->cm_ignore_count = 5;
>> +
> Remove empty line.
Ok.
>> + } else {
>> + usb_if = pcan_usb_pro_dev_if(dev->prev_siblings);
>> + }
>> +
>> + pdev->usb_if = usb_if;
>> + usb_if->dev[dev->ctrl_idx] = dev;
>> +
>> + /* set LED in default state (end of init phase) */
>> + pcan_usb_pro_set_led(dev, 0, 1);
>> +
>> + return 0;
>> +}
>> +
>> +static void pcan_usb_pro_exit(struct peak_usb_device *dev)
>> +{
>> + struct pcan_usb_pro_device *pdev = (struct pcan_usb_pro_device
>> *)dev;
>> +
>> + /*
>> + * when rmmod called before unplug and if down, should reset things
>> + * before leaving
>> + */
>> + if (dev->can.state != CAN_STATE_STOPPED)
>> +
> Remove empty line. Brackets may increase readability here.
Ok and brackets added.
>> + /* set bus off on the corresponding channel */
>> + pcan_usb_pro_set_bus(dev, 0);
>> +
>> + /* if channel #0 (only) */
>> + if (dev->ctrl_idx == 0) {
>> + /* turn off calibration message if any device were opened */
>> + if (pdev->usb_if->dev_opened_count> 0)
>> + pcan_usb_pro_set_ts(dev, 0);
>> +
>> + /* tell the PCAN-USB Pro device driver is being unloaded */
>> + pcan_usb_pro_drv_loaded(dev, 0);
>> + }
>> +}
Thanks!
next prev parent reply other threads:[~2011-12-26 10:55 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-22 13:14 [PATCH] Add support for PEAK System PCAN-USB Pro adapter Stephane Grosjean
2011-12-23 19:57 ` Sebastian Haas
2011-12-26 10:55 ` Grosjean Stephane [this message]
2012-01-10 11:21 ` Wolfgang Grandegger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4EF852A6.3050201@peak-system.com \
--to=s.grosjean@peak-system.com \
--cc=dev@sebastianhaas.info \
--cc=linux-can@vger.kernel.org \
--cc=socketcan@hartkopp.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).