Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758239AbYG2C11 (ORCPT ); Mon, 28 Jul 2008 22:27:27 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1758161AbYG2C0f (ORCPT ); Mon, 28 Jul 2008 22:26:35 -0400 Received: from SpacedOut.fries.net ([67.64.210.234]:58122 "EHLO SpacedOut.fries.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758133AbYG2C0e (ORCPT ); Mon, 28 Jul 2008 22:26:34 -0400 Date: Mon, 28 Jul 2008 21:26:28 -0500 From: David Fries To: Andrew Morton Cc: linux-kernel@vger.kernel.org, Evgeniy Polyakov Subject: [PATCH 24/30] W1: ds2490.c ds_dump_status rework Message-ID: <20080729022628.GX24452@spacedout.fries.net> References: <20080729020433.GA24424@spacedout.fries.net> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="/T7Ys/vy2qfZwzBO" Content-Disposition: inline In-Reply-To: <20080729020433.GA24424@spacedout.fries.net> User-Agent: Mutt/1.5.4i X-Greylist: Sender is SPF-compliant, not delayed by milter-greylist-3.0 (SpacedOut.fries.net [127.0.0.1]); Mon, 28 Jul 2008 21:26:29 -0500 (CDT) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8682 Lines: 258 --/T7Ys/vy2qfZwzBO Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable - add result register #defines - rename ds_dump_status to ds_print_msg - rename ds_recv_status to ds_dump_status - ds_dump_status prints the requested status and no longer reads the status, this is because the second status read can return different data for example the result register - the result register will be printed, though limited to detecting a new device, detecting other values such as a short would require additional reporting methods - ST_EPOF was moved to ds_wait_status to clear the error condition sooner Signed-off-by: David Fries Signed-off-by: Evgeniy Polyakov --- drivers/w1/masters/ds2490.c | 134 +++++++++++++++++++++++++++------------= ---- 1 files changed, 84 insertions(+), 50 deletions(-) diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c index b1ae1a0..0bcdd3f 100644 --- a/drivers/w1/masters/ds2490.c +++ b/drivers/w1/masters/ds2490.c @@ -107,6 +107,17 @@ #define ST_IDLE 0x20 /* DS2490 is currently idle */ #define ST_EPOF 0x80 =20 +/* Result Register flags */ +#define RR_DETECT 0xA5 /* New device detected */ +#define RR_NRS 0x01 /* Reset no presence or ... */ +#define RR_SH 0x02 /* short on reset or set path */ +#define RR_APP 0x04 /* alarming presence on reset */ +#define RR_VPP 0x08 /* 12V expected not seen */ +#define RR_CMP 0x10 /* compare error */ +#define RR_CRC 0x20 /* CRC error detected */ +#define RR_RDP 0x40 /* redirected page */ +#define RR_EOS 0x80 /* end of search error */ + #define SPEED_NORMAL 0x00 #define SPEED_FLEXIBLE 0x01 #define SPEED_OVERDRIVE 0x02 @@ -164,7 +175,6 @@ MODULE_DEVICE_TABLE(usb, ds_id_table); static int ds_probe(struct usb_interface *, const struct usb_device_id *); static void ds_disconnect(struct usb_interface *); =20 -static inline void ds_dump_status(unsigned char *, unsigned char *, int); static int ds_send_control(struct ds_device *, u16, u16); static int ds_send_control_cmd(struct ds_device *, u16, u16); =20 @@ -223,11 +233,6 @@ static int ds_send_control(struct ds_device *dev, u16 = value, u16 index) return err; } =20 -static inline void ds_dump_status(unsigned char *buf, unsigned char *str, = int off) -{ - printk("%45s: %8x\n", str, buf[off]); -} - static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *= st, unsigned char *buf, int size) { @@ -248,54 +253,62 @@ static int ds_recv_status_nodump(struct ds_device *de= v, struct ds_status *st, return count; } =20 -static int ds_recv_status(struct ds_device *dev, struct ds_status *st) +static inline void ds_print_msg(unsigned char *buf, unsigned char *str, in= t off) { - unsigned char buf[64]; - int count, err =3D 0, i; - - memcpy(st, buf, sizeof(*st)); + printk(KERN_INFO "%45s: %8x\n", str, buf[off]); +} =20 - count =3D ds_recv_status_nodump(dev, st, buf, sizeof(buf)); - if (count < 0) - return err; +static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int = count) +{ + int i; =20 - printk("0x%x: count=3D%d, status: ", dev->ep[EP_STATUS], count); + printk(KERN_INFO "0x%x: count=3D%d, status: ", dev->ep[EP_STATUS], count); for (i=3D0; i=3D 16) { - ds_dump_status(buf, "enable flag", 0); - ds_dump_status(buf, "1-wire speed", 1); - ds_dump_status(buf, "strong pullup duration", 2); - ds_dump_status(buf, "programming pulse duration", 3); - ds_dump_status(buf, "pulldown slew rate control", 4); - ds_dump_status(buf, "write-1 low time", 5); - ds_dump_status(buf, "data sample offset/write-0 recovery time", 6); - ds_dump_status(buf, "reserved (test register)", 7); - ds_dump_status(buf, "device status flags", 8); - ds_dump_status(buf, "communication command byte 1", 9); - ds_dump_status(buf, "communication command byte 2", 10); - ds_dump_status(buf, "communication command buffer status", 11); - ds_dump_status(buf, "1-wire data output buffer status", 12); - ds_dump_status(buf, "1-wire data input buffer status", 13); - ds_dump_status(buf, "reserved", 14); - ds_dump_status(buf, "reserved", 15); + ds_print_msg(buf, "enable flag", 0); + ds_print_msg(buf, "1-wire speed", 1); + ds_print_msg(buf, "strong pullup duration", 2); + ds_print_msg(buf, "programming pulse duration", 3); + ds_print_msg(buf, "pulldown slew rate control", 4); + ds_print_msg(buf, "write-1 low time", 5); + ds_print_msg(buf, "data sample offset/write-0 recovery time", + 6); + ds_print_msg(buf, "reserved (test register)", 7); + ds_print_msg(buf, "device status flags", 8); + ds_print_msg(buf, "communication command byte 1", 9); + ds_print_msg(buf, "communication command byte 2", 10); + ds_print_msg(buf, "communication command buffer status", 11); + ds_print_msg(buf, "1-wire data output buffer status", 12); + ds_print_msg(buf, "1-wire data input buffer status", 13); + ds_print_msg(buf, "reserved", 14); + ds_print_msg(buf, "reserved", 15); } - - memcpy(st, buf, sizeof(*st)); - - if (st->status & ST_EPOF) { - printk(KERN_INFO "Resetting device after ST_EPOF.\n"); - err =3D ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); - if (err) - return err; - count =3D ds_recv_status_nodump(dev, st, buf, sizeof(buf)); - if (count < 0) - return err; + for (i =3D 16; i < count; ++i) { + if (buf[i] =3D=3D RR_DETECT) { + ds_print_msg(buf, "new device detect", i); + continue; + } + ds_print_msg(buf, "Result Register Value: ", i); + if (buf[i] & RR_NRS) + printk(KERN_INFO "NRS: Reset no presence or ...\n"); + if (buf[i] & RR_SH) + printk(KERN_INFO "SH: short on reset or set path\n"); + if (buf[i] & RR_APP) + printk(KERN_INFO "APP: alarming presence on reset\n"); + if (buf[i] & RR_VPP) + printk(KERN_INFO "VPP: 12V expected not seen\n"); + if (buf[i] & RR_CMP) + printk(KERN_INFO "CMP: compare error\n"); + if (buf[i] & RR_CRC) + printk(KERN_INFO "CRC: CRC error detected\n"); + if (buf[i] & RR_RDP) + printk(KERN_INFO "RDP: redirected page\n"); + if (buf[i] & RR_EOS) + printk(KERN_INFO "EOS: end of search error\n"); } - - return err; } =20 static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int siz= e) @@ -307,9 +320,14 @@ static int ds_recv_data(struct ds_device *dev, unsigne= d char *buf, int size) err =3D usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DAT= A_IN]), buf, size, &count, 1000); if (err < 0) { + u8 buf[0x20]; + int count; + printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]= )); - ds_recv_status(dev, &st); + + count =3D ds_recv_status_nodump(dev, &st, buf, sizeof(buf)); + ds_dump_status(dev, buf, count); return err; } =20 @@ -390,7 +408,7 @@ int ds_detect(struct ds_device *dev, struct ds_status *= st) if (err) return err; =20 - err =3D ds_recv_status(dev, st); + err =3D ds_dump_status(dev, st); =20 return err; } @@ -415,11 +433,27 @@ static int ds_wait_status(struct ds_device *dev, stru= ct ds_status *st) #endif } while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100); =20 + if (err >=3D 16 && st->status & ST_EPOF) { + printk(KERN_INFO "Resetting device after ST_EPOF.\n"); + ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); + /* Always dump the device status. */ + count =3D 101; + } + + /* Dump the status for errors or if there is extended return data. + * The extended status includes new device detection (maybe someone + * can do something with it). + */ + if (err > 16 || count >=3D 100 || err < 0) + ds_dump_status(dev, buf, err); =20 - if (((err > 16) && (buf[0x10] & 0x01)) || count >=3D 100 || err < 0) { - ds_recv_status(dev, st); + /* Extended data isn't an error. Well, a short is, but the dump + * would have already told the user that and we can't do anything + * about it in software anyway. + */ + if (count >=3D 100 || err < 0) return -1; - } else + else return 0; } =20 --=20 1.4.4.4 --/T7Ys/vy2qfZwzBO Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFIjn/UAI852cse6PARAsZ7AKDPjGdsApD71t41nTcL42PKmGljBQCg0Xzc DxZfiEmajza7YddKCvEd7nU= =epo/ -----END PGP SIGNATURE----- --/T7Ys/vy2qfZwzBO-- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/