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 "; + "$Rev: 1264 $ Ben Collins "; 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 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) 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_new_directory); +EXPORT_SYMBOL(csr1212_attach_keyval_to_directory); +EXPORT_SYMBOL(csr1212_detach_keyval_from_directory); +EXPORT_SYMBOL(csr1212_release_keyval); +EXPORT_SYMBOL(csr1212_read); +EXPORT_SYMBOL(csr1212_parse_keyval); +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_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); +#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 "; + "$Rev: 1299 $ Ben Collins "; /* 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 "; + "$Rev: 1306 $ Ben Collins "; /* * 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; }