Commit 1934b8b6 authored by Ben Collins's avatar Ben Collins Committed by Linus Torvalds

[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: default avatarLinus Torvalds <torvalds@osdl.org>
parent f179bc77
......@@ -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
......
......@@ -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) |
......
......@@ -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;
......
......@@ -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;
......
......@@ -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");
}
......
......@@ -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
......@@ -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;
......
......@@ -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);
......
......@@ -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.");
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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 *
......
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment