]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
[PATCH] Sync up ieee-1394
authorBen Collins <bcollins@debian.org>
Sun, 10 Jul 2005 00:01:23 +0000 (20:01 -0400)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 10 Jul 2005 19:23:23 +0000 (12:23 -0700)
Lots of this patch is trivial code cleanups (static vars were being
intialized to 0, etc).

There's also some fixes for ISO transmits (max buffer handling).
Aswell, we have a few fixes to disable IRM capabilites correctly.  We've
also disabled, by default some generally unused EXPORT symbols for the
sake of cleanliness in the kernel.  However, instead of removing them
completely, we felt it necessary to have a config option that allowed
them to be enabled for the many projects outside of the main kernel tree
that use our API for driver development.

The primary reason for this patch is to revert a MODE6->MODE10 RBC
conversion patch from the SCSI maintainers.  The new conversions handled
directly in the scsi layer do not seem to work for SBP2.  This patch
reverts to our old working code so that users can enjoy using Firewire
disks and dvd drives again.

We are working with the SCSI maintainers to resolve this issue outside
of the main kernel tree.  We'll merge the patch once the SCSI layer's
handling of the MODE10 conversion is working for us.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
13 files changed:
drivers/ieee1394/Kconfig
drivers/ieee1394/csr.c
drivers/ieee1394/csr1212.c
drivers/ieee1394/dma.c
drivers/ieee1394/eth1394.c
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/iso.c
drivers/ieee1394/iso.h
drivers/ieee1394/nodemgr.c
drivers/ieee1394/ohci1394.c
drivers/ieee1394/pcilynx.c
drivers/ieee1394/raw1394.c
drivers/ieee1394/sbp2.c

index 7d58af1ae306f2574c5217a2b4477f9ef1e378f0..25103a0ef9b384c4c58abf31c2c87a6289c8977a 100644 (file)
@@ -66,6 +66,18 @@ config IEEE1394_CONFIG_ROM_IP1394
          with MacOSX and WinXP IP-over-1394), enable this option and the
          eth1394 option below.
 
+config IEEE1394_EXPORT_FULL_API
+       bool "Export all symbols of ieee1394's API"
+       depends on IEEE1394
+       default n
+       help
+         Export all symbols of ieee1394's driver programming interface, even
+         those that are not currently used by the standard IEEE 1394 drivers.
+
+         This option does not affect the interface to userspace applications.
+         Say Y here if you want to compile externally developed drivers that
+         make extended use of ieee1394's API. It is otherwise safe to say N.
+
 comment "Device Drivers"
        depends on IEEE1394
 
index 1b98684aebcd75e6a026c402947b98c64e0470ca..149573db91c5a1dc35d727694de54263f0dc96f3 100644 (file)
@@ -28,6 +28,7 @@
 #include "hosts.h"
 #include "ieee1394.h"
 #include "highlevel.h"
+#include "ieee1394_core.h"
 
 /* Module Parameters */
 /* this module parameter can be used to disable mapping of the FCP registers */
@@ -232,7 +233,7 @@ static void add_host(struct hpsb_host *host)
        host->csr.generation = 2;
 
        bus_info[1] = __constant_cpu_to_be32(0x31333934);
-       bus_info[2] = cpu_to_be32((1 << CSR_IRMC_SHIFT) |
+       bus_info[2] = cpu_to_be32((hpsb_disable_irm ? 0 : 1 << CSR_IRMC_SHIFT) |
                                  (1 << CSR_CMC_SHIFT) |
                                  (1 << CSR_ISC_SHIFT) |
                                  (0 << CSR_BMC_SHIFT) |
index 7c4330e2e875b8e41d92bfc447e3f9aca5c93bc6..61ddd5d37effab34520797ca6811ddafef5cfac1 100644 (file)
@@ -209,7 +209,15 @@ void csr1212_init_local_csr(struct csr1212_csr *csr,
 {
        static const int mr_map[] = { 4, 64, 1024, 0 };
 
+#ifdef __KERNEL__
+       BUG_ON(max_rom & ~0x3);
        csr->max_rom = mr_map[max_rom];
+#else
+       if (max_rom & ~0x3) /* caller supplied invalid argument */
+               csr->max_rom = 0;
+       else
+               csr->max_rom = mr_map[max_rom];
+#endif
        memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len);
 }
 
@@ -533,12 +541,15 @@ struct csr1212_keyval *csr1212_new_icon_descriptor_leaf(u_int32_t version,
        static const int pd[4] = { 0, 4, 16, 256 };
        static const int cs[16] = { 4, 2 };
        struct csr1212_keyval *kv;
-       int palette_size = pd[palette_depth] * cs[color_space];
+       int palette_size;
        int pixel_size = (hscan * vscan + 3) & ~0x3;
 
-       if ((palette_depth && !palette) || !pixels)
+       if (!pixels || (!palette && palette_depth) ||
+           (palette_depth & ~0x3) || (color_space & ~0xf))
                return NULL;
 
+       palette_size = pd[palette_depth] * cs[color_space];
+
        kv = csr1212_new_descriptor_leaf(1, 0, NULL,
                                         palette_size + pixel_size +
                                         CSR1212_ICON_DESCRIPTOR_LEAF_OVERHEAD);
@@ -760,9 +771,9 @@ static int csr1212_append_new_cache(struct csr1212_csr *csr, size_t romsize)
        struct csr1212_csr_rom_cache *cache;
        u_int64_t csr_addr;
 
-       if (!csr || !csr->ops->allocate_addr_range ||
-           !csr->ops->release_addr)
-               return CSR1212_ENOMEM;
+       if (!csr || !csr->ops || !csr->ops->allocate_addr_range ||
+           !csr->ops->release_addr || csr->max_rom < 1)
+               return CSR1212_EINVAL;
 
        /* ROM size must be a multiple of csr->max_rom */
        romsize = (romsize + (csr->max_rom - 1)) & ~(csr->max_rom - 1);
@@ -1145,6 +1156,8 @@ int csr1212_generate_csr_image(struct csr1212_csr *csr)
 
                        /* Make sure the Extended ROM leaf is a multiple of
                         * max_rom in size. */
+                       if (csr->max_rom < 1)
+                               return CSR1212_EINVAL;
                        leaf_size = (cache->len + (csr->max_rom - 1)) &
                                ~(csr->max_rom - 1);
 
@@ -1409,7 +1422,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
        u_int32_t *cache_ptr;
        u_int16_t kv_len = 0;
 
-       if (!csr || !kv)
+       if (!csr || !kv || csr->max_rom < 1)
                return CSR1212_EINVAL;
 
        /* First find which cache the data should be in (or go in if not read
@@ -1572,7 +1585,7 @@ int csr1212_parse_csr(struct csr1212_csr *csr)
        struct csr1212_dentry *dentry;
        int ret;
 
-       if (!csr || !csr->ops->bus_read)
+       if (!csr || !csr->ops || !csr->ops->bus_read)
                return CSR1212_EINVAL;
 
        ret = csr1212_parse_bus_info_block(csr);
@@ -1581,9 +1594,13 @@ int csr1212_parse_csr(struct csr1212_csr *csr)
 
        if (!csr->ops->get_max_rom)
                csr->max_rom = mr_map[0];       /* default value */
-       else
-               csr->max_rom = mr_map[csr->ops->get_max_rom(csr->bus_info_data,
-                                                           csr->private)];
+       else {
+               int i = csr->ops->get_max_rom(csr->bus_info_data,
+                                             csr->private);
+               if (i & ~0x3)
+                       return CSR1212_EINVAL;
+               csr->max_rom = mr_map[i];
+       }
 
        csr->cache_head->layout_head = csr->root_kv;
        csr->cache_head->layout_tail = csr->root_kv;
index 758819d1999dd054b18f7084cb98072bdfc718a9..b79ddb43e7468f1d512c165e8b1581002bdd900b 100644 (file)
@@ -158,7 +158,7 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset,
 
 dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset)
 {
-       unsigned long rem;
+       unsigned long rem = 0;
 
        struct scatterlist *sg = &dma->sglist[dma_region_find(dma, offset, &rem)];
        return sg_dma_address(sg) + rem;
index 654da76bf81146edcc0c2c4d4fb52a2dbfbf4e2b..cd53c174ced171119eabe814919ff570b310006b 100644 (file)
@@ -89,7 +89,7 @@
 #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
 
 static char version[] __devinitdata =
-       "$Rev: 1247 $ Ben Collins <bcollins@debian.org>";
+       "$Rev: 1264 $ Ben Collins <bcollins@debian.org>";
 
 struct fragment_info {
        struct list_head list;
@@ -706,7 +706,7 @@ static void ether1394_host_reset (struct hpsb_host *host)
                return;
 
        dev = hi->dev;
-       priv = netdev_priv(dev);
+       priv = (struct eth1394_priv *)netdev_priv(dev);
 
        /* Reset our private host data, but not our mtu */
        netif_stop_queue (dev);
@@ -1770,7 +1770,7 @@ fail:
 static void ether1394_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
        strcpy (info->driver, driver_name);
-       strcpy (info->version, "$Rev: 1247 $");
+       strcpy (info->version, "$Rev: 1264 $");
        /* FIXME XXX provide sane businfo */
        strcpy (info->bus_info, "ieee1394");
 }
index 629070b83a3360c03abc5a76a752e4ed7ba57902..b248d89de8b4e26c543d5b30c2bd7a187d657059 100644 (file)
@@ -52,7 +52,7 @@
 /*
  * Disable the nodemgr detection and config rom reading functionality.
  */
-static int disable_nodemgr = 0;
+static int disable_nodemgr;
 module_param(disable_nodemgr, int, 0444);
 MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
 
@@ -520,6 +520,9 @@ int hpsb_send_packet(struct hpsb_packet *packet)
 
        if (!packet->no_waiter || packet->expect_response) {
                atomic_inc(&packet->refcnt);
+               /* Set the initial "sendtime" to 10 seconds from now, to
+                  prevent premature expiry.  If a packet takes more than
+                  10 seconds to hit the wire, we have bigger problems :) */
                packet->sendtime = jiffies + 10 * HZ;
                skb_queue_tail(&host->pending_packet_queue, packet->skb);
        }
@@ -1223,9 +1226,7 @@ EXPORT_SYMBOL(hpsb_protocol_class);
 EXPORT_SYMBOL(hpsb_set_packet_complete_task);
 EXPORT_SYMBOL(hpsb_alloc_packet);
 EXPORT_SYMBOL(hpsb_free_packet);
-EXPORT_SYMBOL(hpsb_send_phy_config);
 EXPORT_SYMBOL(hpsb_send_packet);
-EXPORT_SYMBOL(hpsb_send_packet_and_wait);
 EXPORT_SYMBOL(hpsb_reset_bus);
 EXPORT_SYMBOL(hpsb_bus_reset);
 EXPORT_SYMBOL(hpsb_selfid_received);
@@ -1233,6 +1234,10 @@ EXPORT_SYMBOL(hpsb_selfid_complete);
 EXPORT_SYMBOL(hpsb_packet_sent);
 EXPORT_SYMBOL(hpsb_packet_received);
 EXPORT_SYMBOL_GPL(hpsb_disable_irm);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
+EXPORT_SYMBOL(hpsb_send_phy_config);
+EXPORT_SYMBOL(hpsb_send_packet_and_wait);
+#endif
 
 /** ieee1394_transactions.c **/
 EXPORT_SYMBOL(hpsb_get_tlabel);
@@ -1262,9 +1267,11 @@ EXPORT_SYMBOL(hpsb_destroy_hostinfo);
 EXPORT_SYMBOL(hpsb_set_hostinfo_key);
 EXPORT_SYMBOL(hpsb_get_hostinfo_bykey);
 EXPORT_SYMBOL(hpsb_set_hostinfo);
+EXPORT_SYMBOL(highlevel_host_reset);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
 EXPORT_SYMBOL(highlevel_add_host);
 EXPORT_SYMBOL(highlevel_remove_host);
-EXPORT_SYMBOL(highlevel_host_reset);
+#endif
 
 /** nodemgr.c **/
 EXPORT_SYMBOL(hpsb_node_fill_packet);
@@ -1272,7 +1279,9 @@ EXPORT_SYMBOL(hpsb_node_write);
 EXPORT_SYMBOL(hpsb_register_protocol);
 EXPORT_SYMBOL(hpsb_unregister_protocol);
 EXPORT_SYMBOL(ieee1394_bus_type);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
 EXPORT_SYMBOL(nodemgr_for_each_host);
+#endif
 
 /** csr.c **/
 EXPORT_SYMBOL(hpsb_update_config_rom);
@@ -1309,19 +1318,21 @@ EXPORT_SYMBOL(hpsb_iso_wake);
 EXPORT_SYMBOL(hpsb_iso_recv_flush);
 
 /** csr1212.c **/
-EXPORT_SYMBOL(csr1212_create_csr);
-EXPORT_SYMBOL(csr1212_init_local_csr);
-EXPORT_SYMBOL(csr1212_new_immediate);
 EXPORT_SYMBOL(csr1212_new_directory);
-EXPORT_SYMBOL(csr1212_associate_keyval);
 EXPORT_SYMBOL(csr1212_attach_keyval_to_directory);
-EXPORT_SYMBOL(csr1212_new_string_descriptor_leaf);
 EXPORT_SYMBOL(csr1212_detach_keyval_from_directory);
 EXPORT_SYMBOL(csr1212_release_keyval);
-EXPORT_SYMBOL(csr1212_destroy_csr);
 EXPORT_SYMBOL(csr1212_read);
-EXPORT_SYMBOL(csr1212_generate_csr_image);
 EXPORT_SYMBOL(csr1212_parse_keyval);
-EXPORT_SYMBOL(csr1212_parse_csr);
 EXPORT_SYMBOL(_csr1212_read_keyval);
 EXPORT_SYMBOL(_csr1212_destroy_keyval);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
+EXPORT_SYMBOL(csr1212_create_csr);
+EXPORT_SYMBOL(csr1212_init_local_csr);
+EXPORT_SYMBOL(csr1212_new_immediate);
+EXPORT_SYMBOL(csr1212_associate_keyval);
+EXPORT_SYMBOL(csr1212_new_string_descriptor_leaf);
+EXPORT_SYMBOL(csr1212_destroy_csr);
+EXPORT_SYMBOL(csr1212_generate_csr_image);
+EXPORT_SYMBOL(csr1212_parse_csr);
+#endif
index f05759107f7e72c0fe9de781fa3c3fb7f05f575d..615541b8b90f5fa00c312e571a5fb6ac8d3aaa3f 100644 (file)
@@ -62,10 +62,10 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i
        if ((dma_mode < HPSB_ISO_DMA_DEFAULT) || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER))
                dma_mode=HPSB_ISO_DMA_DEFAULT;
 
+       if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
+               irq_interval = buf_packets / 4;
        if (irq_interval == 0)     /* really interrupt for each packet*/
                irq_interval = 1;
-       else if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
-               irq_interval = buf_packets / 4;
 
        if (channel < -1 || channel >= 64)
                return NULL;
@@ -106,6 +106,7 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i
        }
 
        atomic_set(&iso->overflows, 0);
+       iso->bytes_discarded = 0;
        iso->flags = 0;
        iso->prebuffer = 0;
 
@@ -241,12 +242,12 @@ int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer)
        iso->xmit_cycle = cycle;
 
        if (prebuffer < 0)
-               prebuffer = iso->buf_packets;
+               prebuffer = iso->buf_packets - 1;
        else if (prebuffer == 0)
                prebuffer = 1;
 
-       if (prebuffer > iso->buf_packets)
-               prebuffer = iso->buf_packets;
+       if (prebuffer >= iso->buf_packets)
+               prebuffer = iso->buf_packets - 1;
 
        iso->prebuffer = prebuffer;
 
@@ -395,7 +396,7 @@ void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
 }
 
 void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
-                             u16 cycle, u8 channel, u8 tag, u8 sy)
+                             u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy)
 {
        unsigned long flags;
        spin_lock_irqsave(&iso->lock, flags);
@@ -403,10 +404,13 @@ void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
        if (iso->n_ready_packets == iso->buf_packets) {
                /* overflow! */
                atomic_inc(&iso->overflows);
+               /* Record size of this discarded packet */
+               iso->bytes_discarded += total_len;
        } else {
                struct hpsb_iso_packet_info *info = &iso->infos[iso->pkt_dma];
                info->offset = offset;
                info->len = len;
+               info->total_len = total_len;
                info->cycle = cycle;
                info->channel = channel;
                info->tag = tag;
@@ -437,6 +441,17 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets)
 
                iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
                iso->n_ready_packets--;
+
+               /* release memory from packets discarded when queue was full  */
+               if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */
+                       if (iso->bytes_discarded != 0) {
+                               struct hpsb_iso_packet_info inf;
+                               inf.total_len = iso->bytes_discarded;
+                               iso->host->driver->isoctl(iso, RECV_RELEASE,
+                                                       (unsigned long) &inf);
+                               iso->bytes_discarded = 0;
+                       }
+               }
        }
        spin_unlock_irqrestore(&iso->lock, flags);
        return rv;
index fb654d9639a729bf37100cf79d1cb17671f742cf..3efc60b33a88734f40baca223b3654e78fff94f0 100644 (file)
@@ -47,6 +47,14 @@ struct hpsb_iso_packet_info {
        /* 2-bit 'tag' and 4-bit 'sy' fields of the isochronous header */
        __u8 tag;
        __u8 sy;
+
+       /*
+        * length in bytes of the packet including header/trailer.
+        * MUST be at structure end, since the first part of this structure is also 
+        * defined in raw1394.h (i.e. struct raw1394_iso_packet_info), is copied to 
+        * userspace and is accessed there through libraw1394. 
+        */
+       __u16 total_len;
 };
 
 enum hpsb_iso_type { HPSB_ISO_RECV = 0, HPSB_ISO_XMIT = 1 };
@@ -111,6 +119,9 @@ struct hpsb_iso {
        /* how many times the buffer has overflowed or underflowed */
        atomic_t overflows;
 
+       /* Current number of bytes lost in discarded packets */
+       int bytes_discarded;
+
        /* private flags to track initialization progress */
 #define HPSB_ISO_DRIVER_INIT     (1<<0)
 #define HPSB_ISO_DRIVER_STARTED  (1<<1)
@@ -193,7 +204,7 @@ void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error);
 
 /* call after a packet has been received (interrupt context OK) */
 void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
-                             u16 cycle, u8 channel, u8 tag, u8 sy);
+                             u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy);
 
 /* call to wake waiting processes after buffer space has opened up. */
 void hpsb_iso_wake(struct hpsb_iso *iso);
index 9a46c3b44bf8b616aaf9c8755725b90af433610c..bebcc47ab06c2614c0d141d522c7731a212afa08 100644 (file)
@@ -30,7 +30,7 @@
 #include "csr.h"
 #include "nodemgr.h"
 
-static int ignore_drivers = 0;
+static int ignore_drivers;
 module_param(ignore_drivers, int, 0444);
 MODULE_PARM_DESC(ignore_drivers, "Disable automatic probing for drivers.");
 
index b3d3d22fde64d4262a2aae4fe194a2ac4b067d11..a485f47bb21ee8fbbe547bf8a93b9c9d950ac243 100644 (file)
@@ -162,7 +162,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
 
 static char version[] __devinitdata =
-       "$Rev: 1250 $ Ben Collins <bcollins@debian.org>";
+       "$Rev: 1299 $ Ben Collins <bcollins@debian.org>";
 
 /* Module Parameters */
 static int phys_dma = 1;
@@ -483,7 +483,9 @@ static void ohci_initialize(struct ti_ohci *ohci)
        /* Put some defaults to these undefined bus options */
        buf = reg_read(ohci, OHCI1394_BusOptions);
        buf |=  0x60000000; /* Enable CMC and ISC */
-       if (!hpsb_disable_irm)
+       if (hpsb_disable_irm)
+               buf &= ~0x80000000;
+       else
                buf |=  0x80000000; /* Enable IRMC */
        buf &= ~0x00ff0000; /* XXX: Set cyc_clk_acc to zero for now */
        buf &= ~0x18000000; /* Disable PMC and BMC */
@@ -503,8 +505,12 @@ static void ohci_initialize(struct ti_ohci *ohci)
        reg_write(ohci, OHCI1394_LinkControlSet,
                  OHCI1394_LinkControl_CycleTimerEnable |
                  OHCI1394_LinkControl_CycleMaster);
-       set_phy_reg_mask(ohci, 4, PHY_04_LCTRL |
-                        (hpsb_disable_irm ? 0 : PHY_04_CONTENDER));
+       i = get_phy_reg(ohci, 4) | PHY_04_LCTRL;
+       if (hpsb_disable_irm)
+               i &= ~PHY_04_CONTENDER;
+       else
+               i |= PHY_04_CONTENDER;
+       set_phy_reg(ohci, 4, i);
 
        /* Set up self-id dma buffer */
        reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->selfid_buf_bus);
@@ -1566,6 +1572,10 @@ static void ohci_iso_recv_release_block(struct ohci_iso_recv *recv, int block)
 
        struct dma_cmd *next = &recv->block[next_i];
        struct dma_cmd *prev = &recv->block[prev_i];
+       
+       /* ignore out-of-range requests */
+       if ((block < 0) || (block > recv->nblocks))
+               return;
 
        /* 'next' becomes the new end of the DMA chain,
           so disable branch and enable interrupt */
@@ -1593,19 +1603,8 @@ static void ohci_iso_recv_release_block(struct ohci_iso_recv *recv, int block)
 static void ohci_iso_recv_bufferfill_release(struct ohci_iso_recv *recv,
                                             struct hpsb_iso_packet_info *info)
 {
-       int len;
-
        /* release the memory where the packet was */
-       len = info->len;
-
-       /* add the wasted space for padding to 4 bytes */
-       if (len % 4)
-               len += 4 - (len % 4);
-
-       /* add 8 bytes for the OHCI DMA data format overhead */
-       len += 8;
-
-       recv->released_bytes += len;
+       recv->released_bytes += info->total_len;
 
        /* have we released enough memory for one block? */
        while (recv->released_bytes > recv->buf_stride) {
@@ -1637,7 +1636,7 @@ static void ohci_iso_recv_bufferfill_parse(struct hpsb_iso *iso, struct ohci_iso
                /* note: packet layout is as shown in section 10.6.1.1 of the OHCI spec */
 
                unsigned int offset;
-               unsigned short len, cycle;
+               unsigned short len, cycle, total_len;
                unsigned char channel, tag, sy;
 
                unsigned char *p = iso->data_buf.kvirt;
@@ -1688,9 +1687,11 @@ static void ohci_iso_recv_bufferfill_parse(struct hpsb_iso *iso, struct ohci_iso
                /* advance to xferStatus/timeStamp */
                recv->dma_offset += len;
 
+               total_len = len + 8; /* 8 bytes header+trailer in OHCI packet */
                /* payload is padded to 4 bytes */
                if (len % 4) {
                        recv->dma_offset += 4 - (len%4);
+                       total_len += 4 - (len%4);
                }
 
                /* check for wrap-around */
@@ -1724,7 +1725,7 @@ static void ohci_iso_recv_bufferfill_parse(struct hpsb_iso *iso, struct ohci_iso
                        recv->dma_offset -= recv->buf_stride*recv->nblocks;
                }
 
-               hpsb_iso_packet_received(iso, offset, len, cycle, channel, tag, sy);
+               hpsb_iso_packet_received(iso, offset, len, total_len, cycle, channel, tag, sy);
        }
 
        if (wake)
@@ -1850,7 +1851,8 @@ static void ohci_iso_recv_packetperbuf_task(struct hpsb_iso *iso, struct ohci_is
                        tag = hdr[5] >> 6;
                        sy = hdr[4] & 0xF;
 
-                       hpsb_iso_packet_received(iso, offset, packet_len, cycle, channel, tag, sy);
+                       hpsb_iso_packet_received(iso, offset, packet_len,
+                                       recv->buf_stride, cycle, channel, tag, sy);
                }
 
                /* reset the DMA descriptor */
index bdb3a85cafa68507a82616e88b55952f3ff0a057..36074e6eeebb5703e9a9848f40254c000eef65b8 100644 (file)
@@ -76,7 +76,7 @@
 
 
 /* Module Parameters */
-static int skip_eeprom = 0;
+static int skip_eeprom;
 module_param(skip_eeprom, int, 0444);
 MODULE_PARM_DESC(skip_eeprom, "Use generic bus info block instead of serial eeprom (default = 0).");
 
@@ -1422,7 +1422,7 @@ static int __devinit add_card(struct pci_dev *dev,
                i = get_phy_reg(lynx, 4);
                i |= PHY_04_LCTRL;
                if (hpsb_disable_irm)
-                       i &= !PHY_04_CONTENDER;
+                       i &= ~PHY_04_CONTENDER;
                else
                        i |= PHY_04_CONTENDER;
                if (i != -1) set_phy_reg(lynx, 4, i);
index 7419af450bd119f7349fd1357978238a6535529b..b4fa14793fe5f1a421965c8ae550ef72f7ec926f 100644 (file)
@@ -98,7 +98,7 @@ static struct hpsb_address_ops arm_ops = {
 
 static void queue_complete_cb(struct pending_request *req);
 
-static struct pending_request *__alloc_pending_request(int flags)
+static struct pending_request *__alloc_pending_request(unsigned int __nocast flags)
 {
        struct pending_request *req;
 
@@ -2506,9 +2506,12 @@ static int raw1394_iso_send_packets(struct file_info *fi, void __user * uaddr)
        if (copy_from_user(&upackets, uaddr, sizeof(upackets)))
                return -EFAULT;
 
-       if (upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle))
+       if (upackets.n_packets >= fi->iso_handle->buf_packets)
                return -EINVAL;
 
+       if (upackets.n_packets >= hpsb_iso_n_ready(fi->iso_handle))
+               return -EAGAIN;
+
        /* ensure user-supplied buffer is accessible and big enough */
        if (!access_ok(VERIFY_READ, upackets.infos,
                        upackets.n_packets *
index 32368f3428ecfb3a425a3536e6432779e91fe619..fe3e1703fa618d99a446654edd7307c90f8a2be8 100644 (file)
@@ -81,7 +81,7 @@
 #include "sbp2.h"
 
 static char version[] __devinitdata =
-       "$Rev: 1219 $ Ben Collins <bcollins@debian.org>";
+       "$Rev: 1306 $ Ben Collins <bcollins@debian.org>";
 
 /*
  * Module load parameter definitions
@@ -104,7 +104,7 @@ MODULE_PARM_DESC(max_speed, "Force max speed (3 = 800mb, 2 = 400mb default, 1 =
  * down to us at a time (debugging). This might be necessary for very
  * badly behaved sbp2 devices.
  */
-static int serialize_io = 0;
+static int serialize_io;
 module_param(serialize_io, int, 0444);
 MODULE_PARM_DESC(serialize_io, "Serialize all I/O coming down from the scsi drivers (default = 0)");
 
@@ -145,7 +145,7 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device (default = 1)"
  * please submit the logged sbp2_firmware_revision value of this device to
  * the linux1394-devel mailing list.
  */
-static int force_inquiry_hack = 0;
+static int force_inquiry_hack;
 module_param(force_inquiry_hack, int, 0444);
 MODULE_PARM_DESC(force_inquiry_hack, "Force SCSI inquiry hack (default = 0)");
 
@@ -2112,6 +2112,102 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
  */
 static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd)
 {
+       unchar new_cmd[16];
+       u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
+
+       SBP2_DEBUG("sbp2_check_sbp2_command");
+
+       switch (*cmd) {
+
+               case READ_6:
+
+                       if (sbp2_command_conversion_device_type(device_type)) {
+
+                               SBP2_DEBUG("Convert READ_6 to READ_10");
+
+                               /*
+                                * Need to turn read_6 into read_10
+                                */
+                               new_cmd[0] = 0x28;
+                               new_cmd[1] = (cmd[1] & 0xe0);
+                               new_cmd[2] = 0x0;
+                               new_cmd[3] = (cmd[1] & 0x1f);
+                               new_cmd[4] = cmd[2];
+                               new_cmd[5] = cmd[3];
+                               new_cmd[6] = 0x0;
+                               new_cmd[7] = 0x0;
+                               new_cmd[8] = cmd[4];
+                               new_cmd[9] = cmd[5];
+
+                               memcpy(cmd, new_cmd, 10);
+
+                       }
+
+                       break;
+
+               case WRITE_6:
+
+                       if (sbp2_command_conversion_device_type(device_type)) {
+
+                               SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
+
+                               /*
+                                * Need to turn write_6 into write_10
+                                */
+                               new_cmd[0] = 0x2a;
+                               new_cmd[1] = (cmd[1] & 0xe0);
+                               new_cmd[2] = 0x0;
+                               new_cmd[3] = (cmd[1] & 0x1f);
+                               new_cmd[4] = cmd[2];
+                               new_cmd[5] = cmd[3];
+                               new_cmd[6] = 0x0;
+                               new_cmd[7] = 0x0;
+                               new_cmd[8] = cmd[4];
+                               new_cmd[9] = cmd[5];
+
+                               memcpy(cmd, new_cmd, 10);
+
+                       }
+
+                       break;
+
+               case MODE_SENSE:
+
+                       if (sbp2_command_conversion_device_type(device_type)) {
+
+                               SBP2_DEBUG("Convert MODE_SENSE_6 to MODE_SENSE_10");
+
+                               /*
+                                * Need to turn mode_sense_6 into mode_sense_10
+                                */
+                               new_cmd[0] = 0x5a;
+                               new_cmd[1] = cmd[1];
+                               new_cmd[2] = cmd[2];
+                               new_cmd[3] = 0x0;
+                               new_cmd[4] = 0x0;
+                               new_cmd[5] = 0x0;
+                               new_cmd[6] = 0x0;
+                               new_cmd[7] = 0x0;
+                               new_cmd[8] = cmd[4];
+                               new_cmd[9] = cmd[5];
+
+                               memcpy(cmd, new_cmd, 10);
+
+                       }
+
+                       break;
+
+               case MODE_SELECT:
+
+                       /*
+                        * TODO. Probably need to change mode select to 10 byte version
+                        */
+
+               default:
+                       break;
+       }
+
+       return;
 }
 
 /*
@@ -2152,6 +2248,7 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
                                     struct scsi_cmnd *SCpnt)
 {
        u8 *scsi_buf = SCpnt->request_buffer;
+       u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
 
        SBP2_DEBUG("sbp2_check_sbp2_response");
 
@@ -2175,6 +2272,14 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
                                scsi_buf[4] = 36 - 5;
                        }
 
+                       /*
+                        * Check for Simple Direct Access Device and change it to TYPE_DISK
+                        */
+                       if ((scsi_buf[0] & 0x1f) == TYPE_RBC) {
+                               SBP2_DEBUG("Changing TYPE_RBC to TYPE_DISK");
+                               scsi_buf[0] &= 0xe0;
+                       }
+
                        /*
                         * Fix ansi revision and response data format
                         */
@@ -2183,6 +2288,27 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
 
                        break;
 
+               case MODE_SENSE:
+
+                       if (sbp2_command_conversion_device_type(device_type)) {
+
+                               SBP2_DEBUG("Modify mode sense response (10 byte version)");
+
+                               scsi_buf[0] = scsi_buf[1];      /* Mode data length */
+                               scsi_buf[1] = scsi_buf[2];      /* Medium type */
+                               scsi_buf[2] = scsi_buf[3];      /* Device specific parameter */
+                               scsi_buf[3] = scsi_buf[7];      /* Block descriptor length */
+                               memcpy(scsi_buf + 4, scsi_buf + 8, scsi_buf[0]);
+                       }
+
+                       break;
+
+               case MODE_SELECT:
+
+                       /*
+                        * TODO. Probably need to change mode select to 10 byte version
+                        */
+
                default:
                        break;
        }
@@ -2559,8 +2685,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
 static int sbp2scsi_slave_configure (struct scsi_device *sdev)
 {
        blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
-       sdev->use_10_for_rw = 1;
-       sdev->use_10_for_ms = 1;
+
        return 0;
 }