unsigned long data;
/* Max # of packets per frame */
- #define MAX_PACKETS 320
+ /* 320 is enough for NTSC, need to check what PAL is */
+ #define MAX_PACKETS 500
/* a PAGE_SIZE memory pool for allocating CIP headers
static struct hpsb_highlevel *hl_handle; /* = NULL; */
+static LIST_HEAD(dv1394_devfs);
+struct dv1394_devfs_entry {
+ struct list_head list;
+ devfs_handle_t devfs;
+ char name[32];
+ struct dv1394_devfs_entry *parent;
+};
+static spinlock_t dv1394_devfs_lock = SPIN_LOCK_UNLOCKED;
+
/* translate from a struct file* to the corresponding struct video_card* */
static inline struct video_card* file_to_video_card(struct file *file)
/*** DEVFS HELPERS *********************************************************/
-#ifdef CONFIG_DEVFS_FS
-
-static LIST_HEAD(dv1394_devfs);
-struct dv1394_devfs_entry {
- struct list_head list;
- devfs_handle_t devfs;
- char name[32];
- struct dv1394_devfs_entry *parent;
-};
-static spinlock_t dv1394_devfs_lock = SPIN_LOCK_UNLOCKED;
-
struct dv1394_devfs_entry *
dv1394_devfs_find( char *name)
{
kfree(p);
}
}
-#endif /* CONFIG_DEVFS */
/*** IEEE1394 HPSB CALLBACKS ***********************************************/
{
struct ti_ohci *ohci;
char buf[16];
+ struct dv1394_devfs_entry *devfs_entry;
/* We only work with the OHCI-1394 driver */
if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
#endif
#ifdef CONFIG_DEVFS_FS
-{
- struct dv1394_devfs_entry *devfs_entry;
devfs_entry = dv1394_devfs_find("dv");
if (devfs_entry != NULL) {
snprintf(buf, sizeof(buf), "host%d", ohci->id);
dv1394_devfs_add_dir("NTSC", devfs_entry, NULL);
dv1394_devfs_add_dir("PAL", devfs_entry, NULL);
}
-}
#endif
dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
struct net_device *dev;
};
-/* This is our task struct. It's used for the complete_tq callback. */
+/* This is our task struct. It's used for the packet complete callback. */
struct packet_task {
struct sk_buff *skb; /* Socket buffer we are sending */
nodeid_t dest_node; /* Destination of the packet */
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
+#include <linux/tqueue.h>
#include <asm/bitops.h>
#include <asm/byteorder.h>
#include <asm/semaphore.h>
printk("\n");
}
+static void process_complete_tasks(struct hpsb_packet *packet)
+{
+ struct list_head *lh, *next;
+
+ list_for_each_safe(lh, next, &packet->complete_tq) {
+ struct tq_struct *tq = list_entry(lh, struct tq_struct, list);
+ list_del(&tq->list);
+ schedule_task(tq);
+ }
+
+ return;
+}
+
+/**
+ * hpsb_add_packet_complete_task - add a new task for when a packet completes
+ * @packet: the packet whose completion we want the task added to
+ * @tq: the tq_struct describing the task to add
+ */
+void hpsb_add_packet_complete_task(struct hpsb_packet *packet, struct tq_struct *tq)
+{
+ list_add_tail(&tq->list, &packet->complete_tq);
+ return;
+}
/**
* alloc_hpsb_packet - allocate new packet structure
abort_requests(host);
host->in_bus_reset = 1;
host->irm_id = -1;
+ host->is_irm = 0;
host->busmgr_id = -1;
+ host->is_busmgr = 0;
+ host->is_cycmst = 0;
host->node_count = 0;
host->selfid_count = 0;
}
host->reset_retries = 0;
- if (isroot) host->driver->devctl(host, ACT_CYCLE_MASTER, 1);
+ if (isroot) {
+ host->driver->devctl(host, ACT_CYCLE_MASTER, 1);
+ host->is_cycmst = 1;
+ }
atomic_inc(&host->generation);
host->in_bus_reset = 0;
highlevel_host_reset(host);
packet->state = hpsb_complete;
up(&packet->state_change);
up(&packet->state_change);
- run_task_queue(&packet->complete_tq);
+ process_complete_tasks(packet);
return;
}
spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
up(&packet->state_change);
- queue_task(&host->timeout_tq, &tq_timer);
+ schedule_task(&host->timeout_tq);
}
/**
packet->state = hpsb_complete;
up(&packet->state_change);
- run_task_queue(&packet->complete_tq);
+ process_complete_tasks(packet);
}
packet->state = hpsb_complete;
packet->ack_code = ACKX_ABORTED;
up(&packet->state_change);
- run_task_queue(&packet->complete_tq);
+ process_complete_tasks(packet);
}
}
}
}
- if (!list_empty(&host->pending_packets)) {
- queue_task(&host->timeout_tq, &tq_timer);
- }
+ if (!list_empty(&host->pending_packets))
+ schedule_task(&host->timeout_tq);
+
spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
list_for_each(lh, &expiredlist) {
packet->state = hpsb_complete;
packet->ack_code = ACKX_TIMEOUT;
up(&packet->state_change);
- run_task_queue(&packet->complete_tq);
+ process_complete_tasks(packet);
}
}
EXPORT_SYMBOL(hpsb_ref_host);
EXPORT_SYMBOL(hpsb_unref_host);
EXPORT_SYMBOL(hpsb_speedto_str);
+EXPORT_SYMBOL(hpsb_add_packet_complete_task);
EXPORT_SYMBOL(alloc_hpsb_packet);
EXPORT_SYMBOL(free_hpsb_packet);
/* Very core internal, don't care. */
struct semaphore state_change;
- task_queue complete_tq;
+ struct list_head complete_tq;
/* Store jiffies for implementing bus timeouts. */
unsigned long sendtime;
quadlet_t embedded_header[5];
};
+/* add a new task for when a packet completes */
+void hpsb_add_packet_complete_task(struct hpsb_packet *packet, struct tq_struct *tq);
+
static inline struct hpsb_packet *driver_packet(struct list_head *l)
{
return list_entry(l, struct hpsb_packet, driver_list);
ret = hpsb_read(host, nodeid, generation, address, quad, 4);
if (!ret)
break;
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (schedule_timeout (HZ/3))
+ return -1;
}
*quad = be32_to_cpu(*quad);
{
quadlet_t quad;
int size = 0;
+
if (nodemgr_read_quadlet(host, nodeid, generation, address, &quad))
return -1;
+
if (CONFIG_ROM_KEY(quad) == CONFIG_ROM_DESCRIPTOR_LEAF) {
/* This is the offset. */
address += 4 * CONFIG_ROM_VALUE(quad);
/* Now we got the size of the text descriptor leaf. */
size = CONFIG_ROM_LEAF_LENGTH(quad);
}
+
return size;
}
int i, size, ret;
if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation, address, &quad)
- && CONFIG_ROM_KEY(quad) != CONFIG_ROM_DESCRIPTOR_LEAF)
+ || CONFIG_ROM_KEY(quad) != CONFIG_ROM_DESCRIPTOR_LEAF)
return -1;
/* This is the offset. */
printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
static char version[] __devinitdata =
- "$Rev: 555 $ Ben Collins <bcollins@debian.org>";
+ "$Rev: 578 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
MODULE_PARM(attempt_root,"i");
((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10),
((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), ohci->dev->irq,
pci_resource_start(ohci->dev, 0),
- pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE,
+ pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1,
ohci->max_packet_size);
}
{
struct ti_ohci *ohci = host->hostdata;
struct dma_trm_ctx *d;
- unsigned char tcode;
unsigned long flags;
if (packet->data_size > ohci->max_packet_size) {
}
/* Decide wether we have an iso, a request, or a response packet */
- tcode = (packet->header[0]>>4)&0xf;
- if (tcode == TCODE_ISO_DATA) d = &ohci->it_context;
- else if (tcode & 0x02) d = &ohci->at_resp_context;
- else d = &ohci->at_req_context;
+ if (packet->type == hpsb_raw)
+ d = &ohci->at_req_context;
+ else if (packet->tcode == TCODE_ISO_DATA)
+ d = &ohci->it_context;
+ else if (packet->tcode & 0x02)
+ d = &ohci->at_resp_context;
+ else
+ d = &ohci->at_req_context;
spin_lock_irqsave(&d->lock,flags);
}
req->tq.data = req;
- queue_task(&req->tq, &packet->complete_tq);
+ hpsb_add_packet_complete_task(packet, &req->tq);
spin_lock_irq(&fi->reqlists_lock);
list_add_tail(&req->list, &fi->req_pending);
req->tq.data = req;
req->tq.routine = (void (*)(void*))queue_complete_req;
req->req.length = 0;
- queue_task(&req->tq, &packet->complete_tq);
+ hpsb_add_packet_complete_task(packet, &req->tq);
spin_lock_irq(&fi->reqlists_lock);
list_add_tail(&req->list, &fi->req_pending);
#include <asm/byteorder.h>
#include <asm/atomic.h>
#include <asm/system.h>
+#include <asm/io.h>
#include <asm/scatterlist.h>
#ifdef CONFIG_KBUILD_2_5
#include "sbp2.h"
static char version[] __devinitdata =
- "$Rev: 545 $ James Goodwin <jamesg@filanet.com>";
+ "$Rev: 584 $ James Goodwin <jamesg@filanet.com>";
/*
* Module load parameter definitions
*/
/*
- * Change sbp2_max_speed on module load if you have a bad IEEE-1394 controller
- * that has trouble running 2KB packets at 400mb.
+ * Change sbp2_max_speed on module load if you have a bad IEEE-1394
+ * controller that has trouble running 2KB packets at 400mb.
*
* NOTE: On certain OHCI parts I have seen short packets on async transmit
* (probably due to PCI latency/throughput issues with the part). You can
static int sbp2_max_speed = SPEED_400;
/*
- * Set sbp2_serialize_io to 1 if you'd like only one scsi command sent down to
- * us at a time (debugging). This might be necessary for very badly behaved sbp2 devices.
+ * Set sbp2_serialize_io to 1 if you'd like only one scsi command sent
+ * down to us at a time (debugging). This might be necessary for very
+ * badly behaved sbp2 devices.
*/
MODULE_PARM(sbp2_serialize_io,"i");
MODULE_PARM_DESC(sbp2_serialize_io, "Serialize all I/O coming down from the scsi drivers (default = 0)");
static int sbp2_serialize_io = 0; /* serialize I/O - available for debugging purposes */
/*
- * Bump up sbp2_max_sectors if you'd like to support very large sized transfers. Please note
- * that some older sbp2 bridge chips are broken for transfers greater or equal to 128KB.
- * Default is a value of 255 sectors, or just under 128KB (at 512 byte sector size). I can note
- * that the Oxsemi sbp2 chipsets have no problems supporting very large transfer sizes.
+ * Bump up sbp2_max_sectors if you'd like to support very large sized
+ * transfers. Please note that some older sbp2 bridge chips are broken for
+ * transfers greater or equal to 128KB. Default is a value of 255
+ * sectors, or just under 128KB (at 512 byte sector size). I can note that
+ * the Oxsemi sbp2 chipsets have no problems supporting very large
+ * transfer sizes.
*/
MODULE_PARM(sbp2_max_sectors,"i");
MODULE_PARM_DESC(sbp2_max_sectors, "Change max sectors per I/O supported (default = 255)");
static int sbp2_max_sectors = SBP2_MAX_SECTORS;
/*
- * Adjust sbp2_max_outstanding_cmds to tune performance if you have many sbp2 devices attached
- * (or if you need to do some debugging).
+ * Adjust sbp2_max_outstanding_cmds to tune performance if you have many
+ * sbp2 devices attached (or if you need to do some debugging).
*/
MODULE_PARM(sbp2_max_outstanding_cmds,"i");
MODULE_PARM_DESC(sbp2_max_outstanding_cmds, "Change max outstanding concurrent commands (default = 8)");
static int sbp2_max_outstanding_cmds = SBP2SCSI_MAX_OUTSTANDING_CMDS;
/*
- * Adjust sbp2_max_cmds_per_lun to tune performance. Enabling more than one concurrent/linked
- * command per sbp2 device may allow some performance gains, but some older sbp2 devices have
- * firmware bugs resulting in problems when linking commands... so, enable this with care.
- * I can note that the Oxsemi OXFW911 sbp2 chipset works very well with large numbers of
- * concurrent/linked commands. =)
+ * Adjust sbp2_max_cmds_per_lun to tune performance. Enabling more than
+ * one concurrent/linked command per sbp2 device may allow some
+ * performance gains, but some older sbp2 devices have firmware bugs
+ * resulting in problems when linking commands... so, enable this with
+ * care. I can note that the Oxsemi OXFW911 sbp2 chipset works very well
+ * with large numbers of concurrent/linked commands. =)
*/
MODULE_PARM(sbp2_max_cmds_per_lun,"i");
MODULE_PARM_DESC(sbp2_max_cmds_per_lun, "Change max concurrent commands per sbp2 device (default = 1)");
static int sbp2_max_cmds_per_lun = SBP2SCSI_MAX_CMDS_PER_LUN;
/*
- * Exclusive login to sbp2 device? In most cases, the sbp2 driver should do an exclusive login, as it's
- * generally unsafe to have two hosts talking to a single sbp2 device at the same time (filesystem
- * coherency, etc.). If you're running an sbp2 device that supports multiple logins, and you're either
- * running read-only filesystems or some sort of special filesystem supporting multiple hosts, then
- * set sbp2_exclusive_login to zero. Note: The Oxsemi OXFW911 sbp2 chipset supports up to four
+ * Exclusive login to sbp2 device? In most cases, the sbp2 driver should
+ * do an exclusive login, as it's generally unsafe to have two hosts
+ * talking to a single sbp2 device at the same time (filesystem coherency,
+ * etc.). If you're running an sbp2 device that supports multiple logins,
+ * and you're either running read-only filesystems or some sort of special
+ * filesystem supporting multiple hosts, then set sbp2_exclusive_login to
+ * zero. Note: The Oxsemi OXFW911 sbp2 chipset supports up to four
* concurrent logins.
*/
MODULE_PARM(sbp2_exclusive_login,"i");
static int sbp2_exclusive_login = 1;
/*
- * SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on if your sbp2 device
- * is not properly handling the SCSI inquiry command. This hack makes the inquiry look more
- * like a typical MS Windows inquiry.
+ * SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on
+ * if your sbp2 device is not properly handling the SCSI inquiry command.
+ * This hack makes the inquiry look more like a typical MS Windows
+ * inquiry.
+ *
+ * If sbp2_force_inquiry_hack=1 is required for your device to work,
+ * please submit the logged sbp2_firmware_revision value of this device to
+ * the linux1394-devel mailing list.
*/
MODULE_PARM(sbp2_force_inquiry_hack,"i");
MODULE_PARM_DESC(sbp2_force_inquiry_hack, "Force SCSI inquiry hack (default = 0)");
.update = sbp2_update
};
-/* List of device firmware's that require a forced 36 byte inquiry. Note
- * the final 0x0 needs to be there for denoting end of list. */
+/* List of device firmware's that require a forced 36 byte inquiry. */
static u32 sbp2_broken_inquiry_list[] = {
0x00002800, /* Stefan Richter <richtest@bauwesen.tu-cottbus.de> */
- 0x0
+ /* DViCO Momobay CX-1 */
+ 0x00000200 /* Andreas Plesch <plesch@fas.harvard.edu> */
+ /* QPS Fire DVDBurner */
};
+#define NUM_BROKEN_INQUIRY_DEVS \
+ (sizeof(sbp2_broken_inquiry_list)/sizeof(*sbp2_broken_inquiry_list))
+
/**************************************
* General utility functions
**************************************/
request_packet->tq.routine = (void (*)(void*))sbp2util_free_request_packet;
request_packet->tq.data = request_packet;
request_packet->hi_context = hi;
- queue_task(&request_packet->tq, &packet->complete_tq);
+ hpsb_add_packet_complete_task(packet, &request_packet->tq);
/*
* Now, put the packet on the in-use list.
/* Firmware revision */
scsi_id->sbp2_firmware_revision
= CONFIG_ROM_VALUE(ud->quadlets[i]);
- SBP2_DEBUG("sbp2_firmware_revision = %x",
+ if (sbp2_force_inquiry_hack)
+ SBP2_INFO("sbp2_firmware_revision = %x",
+ (unsigned int) scsi_id->sbp2_firmware_revision);
+ else SBP2_DEBUG("sbp2_firmware_revision = %x",
(unsigned int) scsi_id->sbp2_firmware_revision);
break;
/* Check for a blacklisted set of devices that require us to force
* a 36 byte host inquiry. This can be overriden as a module param
- * (to force all hosts).
- *
- * XXX If this does not detect your firmware as being defective,
- * but using the sbp2_force_inquiry_hack allows your device to
- * work, please submit the value of your firmware revision to the
- * linux1394-devel mailing list. */
- for (i = 0; sbp2_broken_inquiry_list[i]; i++) {
+ * (to force all hosts). */
+ for (i = 0; i < NUM_BROKEN_INQUIRY_DEVS; i++) {
if ((scsi_id->sbp2_firmware_revision & 0xffff00) ==
sbp2_broken_inquiry_list[i]) {
SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround",
NODE_BUS_ARGS(scsi_id->ne->nodeid));
scsi_id->workarounds |= SBP2_BREAKAGE_INQUIRY_HACK;
- break; // No need to continue.
+ break; /* No need to continue. */
}
}
}