Commit 1795fc10 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-scsi.bkbits.net/scsi-for-linus-2.5

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 82a86da8 5e81feda
...@@ -196,7 +196,7 @@ struct packet_list { ...@@ -196,7 +196,7 @@ struct packet_list {
/* This implements a circular buffer for incoming samples. */ /* This implements a circular buffer for incoming samples. */
struct buffer { struct buffer {
int head, tail, length, size; size_t head, tail, length, size;
unsigned char data[0]; unsigned char data[0];
}; };
...@@ -623,9 +623,9 @@ static unsigned char *buffer_get_bytes(struct buffer *buffer, int size) ...@@ -623,9 +623,9 @@ static unsigned char *buffer_get_bytes(struct buffer *buffer, int size)
} }
static unsigned char *buffer_put_bytes(struct buffer *buffer, static unsigned char *buffer_put_bytes(struct buffer *buffer,
int max, int *actual) size_t max, size_t *actual)
{ {
int length; size_t length;
unsigned char *p; unsigned char *p;
p = &buffer->data[buffer->tail]; p = &buffer->data[buffer->tail];
...@@ -1089,7 +1089,8 @@ static ssize_t amdtp_write(struct file *file, const char *buffer, size_t count, ...@@ -1089,7 +1089,8 @@ static ssize_t amdtp_write(struct file *file, const char *buffer, size_t count,
{ {
struct stream *s = file->private_data; struct stream *s = file->private_data;
unsigned char *p; unsigned char *p;
int i, length; int i;
size_t length;
if (s->packet_pool == NULL) if (s->packet_pool == NULL)
return -EBADFD; return -EBADFD;
......
...@@ -301,7 +301,8 @@ struct frame { ...@@ -301,7 +301,8 @@ struct frame {
unsigned long data; unsigned long data;
/* Max # of packets per frame */ /* 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 /* a PAGE_SIZE memory pool for allocating CIP headers
......
...@@ -170,6 +170,15 @@ static spinlock_t dv1394_cards_lock = SPIN_LOCK_UNLOCKED; ...@@ -170,6 +170,15 @@ static spinlock_t dv1394_cards_lock = SPIN_LOCK_UNLOCKED;
static struct hpsb_highlevel *hl_handle; /* = NULL; */ 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* */ /* translate from a struct file* to the corresponding struct video_card* */
static inline struct video_card* file_to_video_card(struct file *file) static inline struct video_card* file_to_video_card(struct file *file)
...@@ -2130,7 +2139,7 @@ static int dv1394_procfs_write( struct file *file, ...@@ -2130,7 +2139,7 @@ static int dv1394_procfs_write( struct file *file,
const char *buffer, unsigned long count, void *data) const char *buffer, unsigned long count, void *data)
{ {
int len = 0; int len = 0;
char new_value[64]; char new_value[65];
char *pos; char *pos;
struct video_card *video = (struct video_card*) data; struct video_card *video = (struct video_card*) data;
...@@ -2142,11 +2151,12 @@ static int dv1394_procfs_write( struct file *file, ...@@ -2142,11 +2151,12 @@ static int dv1394_procfs_write( struct file *file,
if (copy_from_user( new_value, buffer, len)) if (copy_from_user( new_value, buffer, len))
return -EFAULT; return -EFAULT;
new_value[len] = 0;
pos = strchr(new_value, '='); pos = strchr(new_value, '=');
if (pos != NULL) { if (pos != NULL) {
int val_len = len - (pos-new_value) - 1; int val_len = len - (pos-new_value) - 1;
char buf[64]; char buf[65];
memset(buf, 0, 64); memset(buf, 0, 65);
strncpy(buf, pos+1, val_len); strncpy(buf, pos+1, val_len);
if (buf[val_len-1] == '\n') buf[val_len-1] = 0; if (buf[val_len-1] == '\n') buf[val_len-1] = 0;
...@@ -2555,17 +2565,6 @@ static struct file_operations dv1394_fops= ...@@ -2555,17 +2565,6 @@ static struct file_operations dv1394_fops=
/*** DEVFS HELPERS *********************************************************/ /*** 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 * struct dv1394_devfs_entry *
dv1394_devfs_find( char *name) dv1394_devfs_find( char *name)
{ {
...@@ -2695,7 +2694,6 @@ void dv1394_devfs_del( char *name) ...@@ -2695,7 +2694,6 @@ void dv1394_devfs_del( char *name)
kfree(p); kfree(p);
} }
} }
#endif /* CONFIG_DEVFS */
/*** IEEE1394 HPSB CALLBACKS ***********************************************/ /*** IEEE1394 HPSB CALLBACKS ***********************************************/
...@@ -2854,6 +2852,7 @@ static void dv1394_add_host (struct hpsb_host *host) ...@@ -2854,6 +2852,7 @@ static void dv1394_add_host (struct hpsb_host *host)
{ {
struct ti_ohci *ohci; struct ti_ohci *ohci;
char buf[16]; char buf[16];
struct dv1394_devfs_entry *devfs_entry;
/* We only work with the OHCI-1394 driver */ /* We only work with the OHCI-1394 driver */
if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME)) if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
...@@ -2875,8 +2874,6 @@ static void dv1394_add_host (struct hpsb_host *host) ...@@ -2875,8 +2874,6 @@ static void dv1394_add_host (struct hpsb_host *host)
#endif #endif
#ifdef CONFIG_DEVFS_FS #ifdef CONFIG_DEVFS_FS
{
struct dv1394_devfs_entry *devfs_entry;
devfs_entry = dv1394_devfs_find("dv"); devfs_entry = dv1394_devfs_find("dv");
if (devfs_entry != NULL) { if (devfs_entry != NULL) {
snprintf(buf, sizeof(buf), "host%d", ohci->id); snprintf(buf, sizeof(buf), "host%d", ohci->id);
...@@ -2884,7 +2881,6 @@ static void dv1394_add_host (struct hpsb_host *host) ...@@ -2884,7 +2881,6 @@ static void dv1394_add_host (struct hpsb_host *host)
dv1394_devfs_add_dir("NTSC", devfs_entry, NULL); dv1394_devfs_add_dir("NTSC", devfs_entry, NULL);
dv1394_devfs_add_dir("PAL", devfs_entry, NULL); dv1394_devfs_add_dir("PAL", devfs_entry, NULL);
} }
}
#endif #endif
dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE); dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
......
...@@ -51,7 +51,7 @@ struct host_info { ...@@ -51,7 +51,7 @@ struct host_info {
struct net_device *dev; 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 packet_task {
struct sk_buff *skb; /* Socket buffer we are sending */ struct sk_buff *skb; /* Socket buffer we are sending */
nodeid_t dest_node; /* Destination of the packet */ nodeid_t dest_node; /* Destination of the packet */
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/tqueue.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
...@@ -66,6 +67,29 @@ static void dump_packet(const char *text, quadlet_t *data, int size) ...@@ -66,6 +67,29 @@ static void dump_packet(const char *text, quadlet_t *data, int size)
printk("\n"); 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 * alloc_hpsb_packet - allocate new packet structure
...@@ -160,7 +184,10 @@ int hpsb_bus_reset(struct hpsb_host *host) ...@@ -160,7 +184,10 @@ int hpsb_bus_reset(struct hpsb_host *host)
abort_requests(host); abort_requests(host);
host->in_bus_reset = 1; host->in_bus_reset = 1;
host->irm_id = -1; host->irm_id = -1;
host->is_irm = 0;
host->busmgr_id = -1; host->busmgr_id = -1;
host->is_busmgr = 0;
host->is_cycmst = 0;
host->node_count = 0; host->node_count = 0;
host->selfid_count = 0; host->selfid_count = 0;
...@@ -354,7 +381,10 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot) ...@@ -354,7 +381,10 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
} }
host->reset_retries = 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); atomic_inc(&host->generation);
host->in_bus_reset = 0; host->in_bus_reset = 0;
highlevel_host_reset(host); highlevel_host_reset(host);
...@@ -378,7 +408,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, ...@@ -378,7 +408,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
packet->state = hpsb_complete; packet->state = hpsb_complete;
up(&packet->state_change); up(&packet->state_change);
up(&packet->state_change); up(&packet->state_change);
run_task_queue(&packet->complete_tq); process_complete_tasks(packet);
return; return;
} }
...@@ -390,7 +420,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, ...@@ -390,7 +420,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
spin_unlock_irqrestore(&host->pending_pkt_lock, flags); spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
up(&packet->state_change); up(&packet->state_change);
queue_task(&host->timeout_tq, &tq_timer); schedule_task(&host->timeout_tq);
} }
/** /**
...@@ -528,7 +558,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data, ...@@ -528,7 +558,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,
packet->state = hpsb_complete; packet->state = hpsb_complete;
up(&packet->state_change); up(&packet->state_change);
run_task_queue(&packet->complete_tq); process_complete_tasks(packet);
} }
...@@ -748,7 +778,7 @@ void abort_requests(struct hpsb_host *host) ...@@ -748,7 +778,7 @@ void abort_requests(struct hpsb_host *host)
packet->state = hpsb_complete; packet->state = hpsb_complete;
packet->ack_code = ACKX_ABORTED; packet->ack_code = ACKX_ABORTED;
up(&packet->state_change); up(&packet->state_change);
run_task_queue(&packet->complete_tq); process_complete_tasks(packet);
} }
} }
...@@ -780,9 +810,9 @@ void abort_timedouts(struct hpsb_host *host) ...@@ -780,9 +810,9 @@ void abort_timedouts(struct hpsb_host *host)
} }
} }
if (!list_empty(&host->pending_packets)) { if (!list_empty(&host->pending_packets))
queue_task(&host->timeout_tq, &tq_timer); schedule_task(&host->timeout_tq);
}
spin_unlock_irqrestore(&host->pending_pkt_lock, flags); spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
list_for_each(lh, &expiredlist) { list_for_each(lh, &expiredlist) {
...@@ -790,7 +820,7 @@ void abort_timedouts(struct hpsb_host *host) ...@@ -790,7 +820,7 @@ void abort_timedouts(struct hpsb_host *host)
packet->state = hpsb_complete; packet->state = hpsb_complete;
packet->ack_code = ACKX_TIMEOUT; packet->ack_code = ACKX_TIMEOUT;
up(&packet->state_change); up(&packet->state_change);
run_task_queue(&packet->complete_tq); process_complete_tasks(packet);
} }
} }
...@@ -1049,6 +1079,7 @@ EXPORT_SYMBOL(hpsb_remove_host); ...@@ -1049,6 +1079,7 @@ EXPORT_SYMBOL(hpsb_remove_host);
EXPORT_SYMBOL(hpsb_ref_host); EXPORT_SYMBOL(hpsb_ref_host);
EXPORT_SYMBOL(hpsb_unref_host); EXPORT_SYMBOL(hpsb_unref_host);
EXPORT_SYMBOL(hpsb_speedto_str); EXPORT_SYMBOL(hpsb_speedto_str);
EXPORT_SYMBOL(hpsb_add_packet_complete_task);
EXPORT_SYMBOL(alloc_hpsb_packet); EXPORT_SYMBOL(alloc_hpsb_packet);
EXPORT_SYMBOL(free_hpsb_packet); EXPORT_SYMBOL(free_hpsb_packet);
......
...@@ -69,7 +69,7 @@ struct hpsb_packet { ...@@ -69,7 +69,7 @@ struct hpsb_packet {
/* Very core internal, don't care. */ /* Very core internal, don't care. */
struct semaphore state_change; struct semaphore state_change;
task_queue complete_tq; struct list_head complete_tq;
/* Store jiffies for implementing bus timeouts. */ /* Store jiffies for implementing bus timeouts. */
unsigned long sendtime; unsigned long sendtime;
...@@ -77,6 +77,9 @@ struct hpsb_packet { ...@@ -77,6 +77,9 @@ struct hpsb_packet {
quadlet_t embedded_header[5]; 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) static inline struct hpsb_packet *driver_packet(struct list_head *l)
{ {
return list_entry(l, struct hpsb_packet, driver_list); return list_entry(l, struct hpsb_packet, driver_list);
......
...@@ -195,6 +195,10 @@ static int nodemgr_read_quadlet(struct hpsb_host *host, ...@@ -195,6 +195,10 @@ static int nodemgr_read_quadlet(struct hpsb_host *host,
ret = hpsb_read(host, nodeid, generation, address, quad, 4); ret = hpsb_read(host, nodeid, generation, address, quad, 4);
if (!ret) if (!ret)
break; break;
set_current_state(TASK_INTERRUPTIBLE);
if (schedule_timeout (HZ/3))
return -1;
} }
*quad = be32_to_cpu(*quad); *quad = be32_to_cpu(*quad);
...@@ -207,8 +211,10 @@ static int nodemgr_size_text_leaf(struct hpsb_host *host, ...@@ -207,8 +211,10 @@ static int nodemgr_size_text_leaf(struct hpsb_host *host,
{ {
quadlet_t quad; quadlet_t quad;
int size = 0; int size = 0;
if (nodemgr_read_quadlet(host, nodeid, generation, address, &quad)) if (nodemgr_read_quadlet(host, nodeid, generation, address, &quad))
return -1; return -1;
if (CONFIG_ROM_KEY(quad) == CONFIG_ROM_DESCRIPTOR_LEAF) { if (CONFIG_ROM_KEY(quad) == CONFIG_ROM_DESCRIPTOR_LEAF) {
/* This is the offset. */ /* This is the offset. */
address += 4 * CONFIG_ROM_VALUE(quad); address += 4 * CONFIG_ROM_VALUE(quad);
...@@ -217,6 +223,7 @@ static int nodemgr_size_text_leaf(struct hpsb_host *host, ...@@ -217,6 +223,7 @@ static int nodemgr_size_text_leaf(struct hpsb_host *host,
/* Now we got the size of the text descriptor leaf. */ /* Now we got the size of the text descriptor leaf. */
size = CONFIG_ROM_LEAF_LENGTH(quad); size = CONFIG_ROM_LEAF_LENGTH(quad);
} }
return size; return size;
} }
...@@ -228,7 +235,7 @@ static int nodemgr_read_text_leaf(struct node_entry *ne, ...@@ -228,7 +235,7 @@ static int nodemgr_read_text_leaf(struct node_entry *ne,
int i, size, ret; int i, size, ret;
if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation, address, &quad) 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; return -1;
/* This is the offset. */ /* This is the offset. */
......
...@@ -154,7 +154,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) ...@@ -154,7 +154,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 555 $ Ben Collins <bcollins@debian.org>"; "$Rev: 578 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */ /* Module Parameters */
MODULE_PARM(attempt_root,"i"); MODULE_PARM(attempt_root,"i");
...@@ -595,7 +595,7 @@ static void ohci_initialize(struct ti_ohci *ohci) ...@@ -595,7 +595,7 @@ static void ohci_initialize(struct ti_ohci *ohci)
((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10), ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10),
((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), ohci->dev->irq, ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), ohci->dev->irq,
pci_resource_start(ohci->dev, 0), 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); ohci->max_packet_size);
} }
...@@ -810,7 +810,6 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet) ...@@ -810,7 +810,6 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
{ {
struct ti_ohci *ohci = host->hostdata; struct ti_ohci *ohci = host->hostdata;
struct dma_trm_ctx *d; struct dma_trm_ctx *d;
unsigned char tcode;
unsigned long flags; unsigned long flags;
if (packet->data_size > ohci->max_packet_size) { if (packet->data_size > ohci->max_packet_size) {
...@@ -821,10 +820,14 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet) ...@@ -821,10 +820,14 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
} }
/* Decide wether we have an iso, a request, or a response packet */ /* Decide wether we have an iso, a request, or a response packet */
tcode = (packet->header[0]>>4)&0xf; if (packet->type == hpsb_raw)
if (tcode == TCODE_ISO_DATA) d = &ohci->it_context; d = &ohci->at_req_context;
else if (tcode & 0x02) d = &ohci->at_resp_context; else if (packet->tcode == TCODE_ISO_DATA)
else d = &ohci->at_req_context; 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); spin_lock_irqsave(&d->lock,flags);
......
...@@ -887,13 +887,14 @@ static ssize_t mem_read(struct file *file, char *buffer, size_t count, ...@@ -887,13 +887,14 @@ static ssize_t mem_read(struct file *file, char *buffer, size_t count,
struct memdata *md = (struct memdata *)file->private_data; struct memdata *md = (struct memdata *)file->private_data;
ssize_t bcount; ssize_t bcount;
size_t alignfix; size_t alignfix;
int off = (int)*offset; /* avoid useless 64bit-arithmetic */ loff_t off = *offset; /* avoid useless 64bit-arithmetic */
ssize_t retval; ssize_t retval;
void *membase; void *membase;
if (*offset != off) /* Check for EOF before we trust wrap */ if (*offset != off) /* Check for EOF before we trust wrap */
return 0; return 0;
/* FIXME: Signed wrap is undefined in C - wants fixing up */
if (off + count > off) if (off + count > off)
return 0; return 0;
......
...@@ -743,7 +743,7 @@ static int handle_remote_request(struct file_info *fi, ...@@ -743,7 +743,7 @@ static int handle_remote_request(struct file_info *fi,
} }
req->tq.data = req; 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); spin_lock_irq(&fi->reqlists_lock);
list_add_tail(&req->list, &fi->req_pending); list_add_tail(&req->list, &fi->req_pending);
...@@ -786,7 +786,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req, ...@@ -786,7 +786,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
req->tq.data = req; req->tq.data = req;
req->tq.routine = (void (*)(void*))queue_complete_req; req->tq.routine = (void (*)(void*))queue_complete_req;
req->req.length = 0; 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); spin_lock_irq(&fi->reqlists_lock);
list_add_tail(&req->list, &fi->req_pending); list_add_tail(&req->list, &fi->req_pending);
......
...@@ -327,6 +327,7 @@ ...@@ -327,6 +327,7 @@
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
#ifdef CONFIG_KBUILD_2_5 #ifdef CONFIG_KBUILD_2_5
...@@ -350,15 +351,15 @@ ...@@ -350,15 +351,15 @@
#include "sbp2.h" #include "sbp2.h"
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 545 $ James Goodwin <jamesg@filanet.com>"; "$Rev: 584 $ James Goodwin <jamesg@filanet.com>";
/* /*
* Module load parameter definitions * Module load parameter definitions
*/ */
/* /*
* Change sbp2_max_speed on module load if you have a bad IEEE-1394 controller * Change sbp2_max_speed on module load if you have a bad IEEE-1394
* that has trouble running 2KB packets at 400mb. * controller that has trouble running 2KB packets at 400mb.
* *
* NOTE: On certain OHCI parts I have seen short packets on async transmit * 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 * (probably due to PCI latency/throughput issues with the part). You can
...@@ -374,48 +375,54 @@ MODULE_PARM_DESC(sbp2_max_speed, "Force max speed (2 = 400mb default, 1 = 200mb, ...@@ -374,48 +375,54 @@ MODULE_PARM_DESC(sbp2_max_speed, "Force max speed (2 = 400mb default, 1 = 200mb,
static int sbp2_max_speed = SPEED_400; static int sbp2_max_speed = SPEED_400;
/* /*
* Set sbp2_serialize_io to 1 if you'd like only one scsi command sent down to * Set sbp2_serialize_io to 1 if you'd like only one scsi command sent
* us at a time (debugging). This might be necessary for very badly behaved sbp2 devices. * 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(sbp2_serialize_io,"i");
MODULE_PARM_DESC(sbp2_serialize_io, "Serialize all I/O coming down from the scsi drivers (default = 0)"); 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 */ 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 * Bump up sbp2_max_sectors if you'd like to support very large sized
* that some older sbp2 bridge chips are broken for transfers greater or equal to 128KB. * transfers. Please note that some older sbp2 bridge chips are broken for
* Default is a value of 255 sectors, or just under 128KB (at 512 byte sector size). I can note * transfers greater or equal to 128KB. Default is a value of 255
* that the Oxsemi sbp2 chipsets have no problems supporting very large transfer sizes. * 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(sbp2_max_sectors,"i");
MODULE_PARM_DESC(sbp2_max_sectors, "Change max sectors per I/O supported (default = 255)"); MODULE_PARM_DESC(sbp2_max_sectors, "Change max sectors per I/O supported (default = 255)");
static int sbp2_max_sectors = SBP2_MAX_SECTORS; static int sbp2_max_sectors = SBP2_MAX_SECTORS;
/* /*
* Adjust sbp2_max_outstanding_cmds to tune performance if you have many sbp2 devices attached * Adjust sbp2_max_outstanding_cmds to tune performance if you have many
* (or if you need to do some debugging). * sbp2 devices attached (or if you need to do some debugging).
*/ */
MODULE_PARM(sbp2_max_outstanding_cmds,"i"); MODULE_PARM(sbp2_max_outstanding_cmds,"i");
MODULE_PARM_DESC(sbp2_max_outstanding_cmds, "Change max outstanding concurrent commands (default = 8)"); MODULE_PARM_DESC(sbp2_max_outstanding_cmds, "Change max outstanding concurrent commands (default = 8)");
static int sbp2_max_outstanding_cmds = SBP2SCSI_MAX_OUTSTANDING_CMDS; 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 * Adjust sbp2_max_cmds_per_lun to tune performance. Enabling more than
* command per sbp2 device may allow some performance gains, but some older sbp2 devices have * one concurrent/linked command per sbp2 device may allow some
* firmware bugs resulting in problems when linking commands... so, enable this with care. * performance gains, but some older sbp2 devices have firmware bugs
* I can note that the Oxsemi OXFW911 sbp2 chipset works very well with large numbers of * resulting in problems when linking commands... so, enable this with
* concurrent/linked commands. =) * 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(sbp2_max_cmds_per_lun,"i");
MODULE_PARM_DESC(sbp2_max_cmds_per_lun, "Change max concurrent commands per sbp2 device (default = 1)"); 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; 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 * Exclusive login to sbp2 device? In most cases, the sbp2 driver should
* generally unsafe to have two hosts talking to a single sbp2 device at the same time (filesystem * do an exclusive login, as it's generally unsafe to have two hosts
* coherency, etc.). If you're running an sbp2 device that supports multiple logins, and you're either * talking to a single sbp2 device at the same time (filesystem coherency,
* running read-only filesystems or some sort of special filesystem supporting multiple hosts, then * etc.). If you're running an sbp2 device that supports multiple logins,
* set sbp2_exclusive_login to zero. Note: The Oxsemi OXFW911 sbp2 chipset supports up to four * 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. * concurrent logins.
*/ */
MODULE_PARM(sbp2_exclusive_login,"i"); MODULE_PARM(sbp2_exclusive_login,"i");
...@@ -423,9 +430,14 @@ MODULE_PARM_DESC(sbp2_exclusive_login, "Exclusive login to sbp2 device (default ...@@ -423,9 +430,14 @@ MODULE_PARM_DESC(sbp2_exclusive_login, "Exclusive login to sbp2 device (default
static int sbp2_exclusive_login = 1; static int sbp2_exclusive_login = 1;
/* /*
* SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on if your sbp2 device * SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on
* is not properly handling the SCSI inquiry command. This hack makes the inquiry look more * if your sbp2 device is not properly handling the SCSI inquiry command.
* like a typical MS Windows inquiry. * 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(sbp2_force_inquiry_hack,"i");
MODULE_PARM_DESC(sbp2_force_inquiry_hack, "Force SCSI inquiry hack (default = 0)"); MODULE_PARM_DESC(sbp2_force_inquiry_hack, "Force SCSI inquiry hack (default = 0)");
...@@ -550,13 +562,17 @@ static struct hpsb_protocol_driver sbp2_driver = { ...@@ -550,13 +562,17 @@ static struct hpsb_protocol_driver sbp2_driver = {
.update = sbp2_update .update = sbp2_update
}; };
/* List of device firmware's that require a forced 36 byte inquiry. Note /* List of device firmware's that require a forced 36 byte inquiry. */
* the final 0x0 needs to be there for denoting end of list. */
static u32 sbp2_broken_inquiry_list[] = { static u32 sbp2_broken_inquiry_list[] = {
0x00002800, /* Stefan Richter <richtest@bauwesen.tu-cottbus.de> */ 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 * General utility functions
**************************************/ **************************************/
...@@ -787,7 +803,7 @@ sbp2util_allocate_write_request_packet(struct sbp2scsi_host_info *hi, ...@@ -787,7 +803,7 @@ sbp2util_allocate_write_request_packet(struct sbp2scsi_host_info *hi,
request_packet->tq.routine = (void (*)(void*))sbp2util_free_request_packet; request_packet->tq.routine = (void (*)(void*))sbp2util_free_request_packet;
request_packet->tq.data = request_packet; request_packet->tq.data = request_packet;
request_packet->hi_context = hi; 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. * Now, put the packet on the in-use list.
...@@ -1914,7 +1930,10 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id) ...@@ -1914,7 +1930,10 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id)
/* Firmware revision */ /* Firmware revision */
scsi_id->sbp2_firmware_revision scsi_id->sbp2_firmware_revision
= CONFIG_ROM_VALUE(ud->quadlets[i]); = 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); (unsigned int) scsi_id->sbp2_firmware_revision);
break; break;
...@@ -1948,19 +1967,14 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id) ...@@ -1948,19 +1967,14 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id)
/* Check for a blacklisted set of devices that require us to force /* 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 * a 36 byte host inquiry. This can be overriden as a module param
* (to force all hosts). * (to force all hosts). */
* for (i = 0; i < NUM_BROKEN_INQUIRY_DEVS; i++) {
* 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++) {
if ((scsi_id->sbp2_firmware_revision & 0xffff00) == if ((scsi_id->sbp2_firmware_revision & 0xffff00) ==
sbp2_broken_inquiry_list[i]) { sbp2_broken_inquiry_list[i]) {
SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround", SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround",
NODE_BUS_ARGS(scsi_id->ne->nodeid)); NODE_BUS_ARGS(scsi_id->ne->nodeid));
scsi_id->workarounds |= SBP2_BREAKAGE_INQUIRY_HACK; scsi_id->workarounds |= SBP2_BREAKAGE_INQUIRY_HACK;
break; // No need to continue. break; /* No need to continue. */
} }
} }
} }
......
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