summaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394
diff options
context:
space:
mode:
authorBen Collins <bcollins@debian.org>2005-07-09 20:01:23 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-10 12:23:23 -0700
commit1934b8b6561ee7804b0a671b48cf642fcd936b2c (patch)
tree25c975176441aceedd2faae515121374f6f75750 /drivers/ieee1394
parentf179bc77d09b9087bfc559d0368bba350342ac76 (diff)
downloadblackbird-op-linux-1934b8b6561ee7804b0a671b48cf642fcd936b2c.tar.gz
blackbird-op-linux-1934b8b6561ee7804b0a671b48cf642fcd936b2c.zip
[PATCH] Sync up ieee-1394
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>
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r--drivers/ieee1394/Kconfig12
-rw-r--r--drivers/ieee1394/csr.c3
-rw-r--r--drivers/ieee1394/csr1212.c37
-rw-r--r--drivers/ieee1394/dma.c2
-rw-r--r--drivers/ieee1394/eth1394.c6
-rw-r--r--drivers/ieee1394/ieee1394_core.c35
-rw-r--r--drivers/ieee1394/iso.c27
-rw-r--r--drivers/ieee1394/iso.h13
-rw-r--r--drivers/ieee1394/nodemgr.c2
-rw-r--r--drivers/ieee1394/ohci1394.c40
-rw-r--r--drivers/ieee1394/pcilynx.c4
-rw-r--r--drivers/ieee1394/raw1394.c7
-rw-r--r--drivers/ieee1394/sbp2.c135
13 files changed, 260 insertions, 63 deletions
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
index 7d58af1ae306..25103a0ef9b3 100644
--- a/drivers/ieee1394/Kconfig
+++ b/drivers/ieee1394/Kconfig
@@ -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
diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c
index 1b98684aebcd..149573db91c5 100644
--- a/drivers/ieee1394/csr.c
+++ b/drivers/ieee1394/csr.c
@@ -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) |
diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c
index 7c4330e2e875..61ddd5d37eff 100644
--- a/drivers/ieee1394/csr1212.c
+++ b/drivers/ieee1394/csr1212.c
@@ -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;
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 758819d1999d..b79ddb43e746 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -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;
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 654da76bf811..cd53c174ced1 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -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");
}
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index 629070b83a33..b248d89de8b4 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -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
diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c
index f05759107f7e..615541b8b90f 100644
--- a/drivers/ieee1394/iso.c
+++ b/drivers/ieee1394/iso.c
@@ -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;
diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h
index fb654d9639a7..3efc60b33a88 100644
--- a/drivers/ieee1394/iso.h
+++ b/drivers/ieee1394/iso.h
@@ -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);
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 9a46c3b44bf8..bebcc47ab06c 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -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.");
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index b3d3d22fde64..a485f47bb21e 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -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 */
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index bdb3a85cafa6..36074e6eeebb 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -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);
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 7419af450bd1..b4fa14793fe5 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -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 *
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 32368f3428ec..fe3e1703fa61 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -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");
@@ -2176,6 +2273,14 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
}
/*
+ * 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
*/
scsi_buf[2] |= 2;
@@ -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;
}
OpenPOWER on IntegriCloud