w1: ds2490: support block sizes larger than 128 bytes in ds_read_block
[linux-2.6-microblaze.git] / drivers / w1 / masters / ds2490.c
index 5f5b97e..e1cac07 100644 (file)
@@ -98,6 +98,8 @@
 #define ST_EPOF                                0x80
 /* Status transfer size, 16 bytes status, 16 byte result flags */
 #define ST_SIZE                                0x20
+/* 1-wire data i/o fifo size, 128 bytes */
+#define FIFO_SIZE                      0x80
 
 /* Result Register flags */
 #define RR_DETECT                      0xA5 /* New device detected */
@@ -614,14 +616,11 @@ static int ds_read_byte(struct ds_device *dev, u8 *byte)
        return 0;
 }
 
-static int ds_read_block(struct ds_device *dev, u8 *buf, int len)
+static int read_block_chunk(struct ds_device *dev, u8 *buf, int len)
 {
        struct ds_status st;
        int err;
 
-       if (len > 64*1024)
-               return -E2BIG;
-
        memset(buf, 0xFF, len);
 
        err = ds_send_data(dev, buf, len);
@@ -640,6 +639,24 @@ static int ds_read_block(struct ds_device *dev, u8 *buf, int len)
        return err;
 }
 
+static int ds_read_block(struct ds_device *dev, u8 *buf, int len)
+{
+       int err, to_read, rem = len;
+
+       if (len > 64 * 1024)
+               return -E2BIG;
+
+       do {
+               to_read = rem <= FIFO_SIZE ? rem : FIFO_SIZE;
+               err = read_block_chunk(dev, &buf[len - rem], to_read);
+               if (err < 0)
+                       return err;
+               rem -= to_read;
+       } while (rem);
+
+       return err;
+}
+
 static int ds_write_block(struct ds_device *dev, u8 *buf, int len)
 {
        int err;