From ccdba6ab4689b9bad6d44d7227526f40fb107fdf Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Fri, 25 Jul 2003 00:40:53 -0700 Subject: [PATCH] [PATCH] Update IEEE1394 (r1014) misc: - Consolidate and make consistent, the NODE_BUS_{FMT,ARGS} macros. - Add HPSB_VERBOSE() macro to make VERBOSEDEBUG code a little cleaner. ieee1394 : - Replace panic() with BUG and return value in dma routine. - Reset reset_retries on success or loop recover. - Add RECV_FLUSH to flush buffers on > 1 irq interval or in buffer-fill mode. - Probe logic-unit-subdirectories as children of the unit-dir. - Fix compile warning in nodemgr thread. - Replace tightly scheduled timeout loop with a 50ms timer. - Better return and usage of BUG_ON() in dma handler. - Calculate timeout expiry interval at change instead of at every timeout check. SBP2 : - Fix logical-unit-directory LUN's. - Remove procfs interface. - Fix usage of initdata after init. Host con : - Change irq output to use __irq_itoa() for sparc. - Do more to notify bus when module is unloaded, to clear IRM, etc. ohci1394 : Fix endianess of async stream packet headers. --- drivers/ieee1394/csr.c | 38 ++- drivers/ieee1394/csr.h | 1 + drivers/ieee1394/dma.c | 6 +- drivers/ieee1394/dv1394-private.h | 2 +- drivers/ieee1394/dv1394.c | 291 +---------------------- drivers/ieee1394/dv1394.h | 2 +- drivers/ieee1394/eth1394.c | 6 +- drivers/ieee1394/highlevel.h | 1 + drivers/ieee1394/hosts.c | 14 +- drivers/ieee1394/hosts.h | 9 +- drivers/ieee1394/ieee1394-ioctl.h | 2 + drivers/ieee1394/ieee1394_core.c | 82 +++---- drivers/ieee1394/ieee1394_core.h | 6 +- drivers/ieee1394/ieee1394_transactions.c | 4 +- drivers/ieee1394/ieee1394_types.h | 11 +- drivers/ieee1394/iso.c | 7 + drivers/ieee1394/iso.h | 4 + drivers/ieee1394/nodemgr.c | 153 ++++++------ drivers/ieee1394/nodemgr.h | 14 +- drivers/ieee1394/ohci1394.c | 78 ++++-- drivers/ieee1394/pcilynx.c | 40 +++- drivers/ieee1394/raw1394.c | 6 +- drivers/ieee1394/sbp2.c | 136 ++++------- drivers/ieee1394/video1394.c | 1 - 24 files changed, 333 insertions(+), 581 deletions(-) diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c index bf3bf63898cc9..bd394d9385387 100644 --- a/drivers/ieee1394/csr.c +++ b/drivers/ieee1394/csr.c @@ -89,6 +89,37 @@ static void host_reset(struct hpsb_host *host) 0x3f1)); } +/* + * HI == seconds (bits 0:2) + * LO == fraction units of 1/8000 of a second, as per 1394 (bits 19:31) + * + * Convert to units and then to HZ, for comparison to jiffies. + * + * By default this will end up being 800 units, or 100ms (125usec per + * unit). + * + * NOTE: The spec says 1/8000, but also says we can compute based on 1/8192 + * like CSR specifies. Should make our math less complex. + */ +static inline void calculate_expire(struct csr_control *csr) +{ + unsigned long units; + + /* Take the seconds, and convert to units */ + units = (unsigned long)(csr->split_timeout_hi & 0x07) << 13; + + /* Add in the fractional units */ + units += (unsigned long)(csr->split_timeout_lo >> 19); + + /* Convert to jiffies */ + csr->expire = (unsigned long)(units * HZ) >> 13UL; + + /* Just to keep from rounding low */ + csr->expire++; + + HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%lu", csr->expire, HZ); +} + static void add_host(struct hpsb_host *host) { @@ -100,6 +131,7 @@ static void add_host(struct hpsb_host *host) host->csr.node_ids = 0; host->csr.split_timeout_hi = 0; host->csr.split_timeout_lo = 800 << 19; + calculate_expire(&host->csr); host->csr.cycle_time = 0; host->csr.bus_time = 0; host->csr.bus_manager_id = 0x3f; @@ -336,10 +368,12 @@ static int write_regs(struct hpsb_host *host, int nodeid, int destid, case CSR_SPLIT_TIMEOUT_HI: host->csr.split_timeout_hi = be32_to_cpu(*(data++)) & 0x00000007; + calculate_expire(&host->csr); out; case CSR_SPLIT_TIMEOUT_LO: host->csr.split_timeout_lo = be32_to_cpu(*(data++)) & 0xfff80000; + calculate_expire(&host->csr); out; /* address gap */ @@ -410,7 +444,7 @@ static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store, * eventually. */ HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release " "broadcast channel 31. Ignoring.", - NODE_BUS_ARGS(nodeid)); + NODE_BUS_ARGS(host, nodeid)); data &= ~0x1; /* keep broadcast channel allocated */ } @@ -556,7 +590,7 @@ static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store, * eventually. */ HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release " "broadcast channel 31. Ignoring.", - NODE_BUS_ARGS(nodeid)); + NODE_BUS_ARGS(host, nodeid)); data &= ~0x100000000ULL; /* keep broadcast channel allocated */ } diff --git a/drivers/ieee1394/csr.h b/drivers/ieee1394/csr.h index 512fca0a5eaca..fb01094ea7e94 100644 --- a/drivers/ieee1394/csr.h +++ b/drivers/ieee1394/csr.h @@ -41,6 +41,7 @@ struct csr_control { quadlet_t state; quadlet_t node_ids; quadlet_t split_timeout_hi, split_timeout_lo; + unsigned long expire; // Calculated from split_timeout quadlet_t cycle_time; quadlet_t bus_time; quadlet_t bus_manager_id; diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c index fed18e1d4035d..25db9c4348d53 100644 --- a/drivers/ieee1394/dma.c +++ b/drivers/ieee1394/dma.c @@ -151,13 +151,15 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset, for (i = 0; i < dma->n_dma_pages; i++) { if (off < sg_dma_len(&dma->sglist[i])) { *rem = off; - return i; + break; } off -= sg_dma_len(&dma->sglist[i]); } - panic("dma_region_find: offset %lu beyond end of DMA mapping\n", offset); + BUG_ON(i >= dma->n_dma_pages); + + return i; } dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset) diff --git a/drivers/ieee1394/dv1394-private.h b/drivers/ieee1394/dv1394-private.h index 4d61458f49ffa..046988346d8f2 100644 --- a/drivers/ieee1394/dv1394-private.h +++ b/drivers/ieee1394/dv1394-private.h @@ -1,7 +1,7 @@ /* * dv1394-private.h - DV input/output over IEEE 1394 on OHCI chips * Copyright (C)2001 Daniel Maas - * receive, proc_fs by Dan Dennedy + * receive by Dan Dennedy * * based on: * video1394.h - driver for OHCI 1394 boards diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index a876cbf825988..0ad9086bd5f2f 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c @@ -1,7 +1,7 @@ /* * dv1394.c - DV input/output over IEEE 1394 on OHCI chips * Copyright (C)2001 Daniel Maas - * receive, proc_fs by Dan Dennedy + * receive by Dan Dennedy * * based on: * video1394.c - video driver for OHCI 1394 boards @@ -80,7 +80,6 @@ - add proc fs interface to set cip_n, cip_d, syt_offset, and video signal - expose xmit and recv as separate devices (not exclusive) - expose NTSC and PAL as separate devices (can be overridden) - - read/edit channel in procfs */ @@ -102,7 +101,6 @@ #include #include #include -#include #include #include #include @@ -1103,7 +1101,7 @@ static int do_dv1394_init_default(struct video_card *video) init.api_version = DV1394_API_VERSION; init.n_frames = DV1394_MAX_FRAMES / 4; - /* the following are now set via proc_fs or devfs */ + /* the following are now set via devfs */ init.channel = video->channel; init.format = video->pal_or_ntsc; init.cip_n = video->cip_n; @@ -1857,244 +1855,6 @@ static int dv1394_release(struct inode *inode, struct file *file) } -/*** PROC_FS INTERFACE ******************************************************/ -#ifdef CONFIG_PROC_FS -static LIST_HEAD(dv1394_procfs); -struct dv1394_procfs_entry { - struct list_head list; - struct proc_dir_entry *procfs; - char name[32]; - struct dv1394_procfs_entry *parent; -}; -static spinlock_t dv1394_procfs_lock = SPIN_LOCK_UNLOCKED; - -static int dv1394_procfs_read( char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct video_card *video = (struct video_card*) data; - - snprintf( page, count, - "\ -format=%s\n\ -channel=%d\n\ -cip_n=%lu\n\ -cip_d=%lu\n\ -syt_offset=%u\n", - (video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"), - video->channel, - video->cip_n, video->cip_d, video->syt_offset ); - return strlen(page); -} - -/* lifted from the stallion.c driver */ -#undef TOLOWER -#define TOLOWER(x) ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x)) -static unsigned long atol(char *str) -{ - unsigned long val; - int base, c; - char *sp; - - val = 0; - sp = str; - if ((*sp == '0') && (*(sp+1) == 'x')) { - base = 16; - sp += 2; - } else if (*sp == '0') { - base = 8; - sp++; - } else { - base = 10; - } - - for (; (*sp != 0); sp++) { - c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0'); - if ((c < 0) || (c >= base)) { - printk(KERN_ERR "dv1394: atol() invalid argument %s\n", str); - val = 0; - break; - } - val = (val * base) + c; - } - return(val); -} - -static int dv1394_procfs_write( struct file *file, - const char *buffer, unsigned long count, void *data) -{ - int len = 0; - char new_value[65]; - char *pos; - struct video_card *video = (struct video_card*) data; - - if (count > 64) - len = 64; - else - len = count; - - if (copy_from_user( new_value, buffer, len)) - return -EFAULT; - - new_value[len] = 0; - pos = strchr(new_value, '='); - if (pos != NULL) { - int val_len = len - (pos-new_value) - 1; - char buf[65]; - memset(buf, 0, 65); - strncpy(buf, pos+1, val_len); - if (buf[val_len-1] == '\n') buf[val_len-1] = 0; - - if (strnicmp( new_value, "format", (pos-new_value)) == 0) { - if (strnicmp( buf, "NTSC", val_len) == 0) - video->pal_or_ntsc = DV1394_NTSC; - else if (strnicmp( buf, "PAL", val_len) == 0) - video->pal_or_ntsc = DV1394_PAL; - - } else if (strnicmp( new_value, "cip_n", (pos-new_value)) == 0) { - video->cip_n = atol(buf); - } else if (strnicmp( new_value, "cip_d", (pos-new_value)) == 0) { - video->cip_d = atol(buf); - } else if (strnicmp( new_value, "syt_offset", (pos-new_value)) == 0) { - video->syt_offset = atol(buf); - } else if (strnicmp( new_value, "channel", (pos-new_value)) == 0) { - video->channel = atol(buf); - } - } - - return len; -} - -struct dv1394_procfs_entry * -dv1394_procfs_find( char *name) -{ - struct list_head *lh; - struct dv1394_procfs_entry *p; - - spin_lock( &dv1394_procfs_lock); - if (!list_empty(&dv1394_procfs)) { - list_for_each(lh, &dv1394_procfs) { - p = list_entry(lh, struct dv1394_procfs_entry, list); - if (!strncmp(p->name, name, sizeof(p->name))) { - spin_unlock( &dv1394_procfs_lock); - return p; - } - } - } - spin_unlock( &dv1394_procfs_lock); - return NULL; -} - -static int dv1394_procfs_add_entry(struct video_card *video) -{ - char buf[32]; - struct dv1394_procfs_entry *p; - struct dv1394_procfs_entry *parent; - - p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL); - if (!p) { - printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n"); - goto err; - } - memset(p, 0, sizeof(struct dv1394_procfs_entry)); - - snprintf(buf, sizeof(buf), "dv/host%d/%s", (video->id>>2), - (video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL")); - - parent = dv1394_procfs_find(buf); - if (parent == NULL) { - printk(KERN_ERR "dv1394: unable to locate parent procfs of %s\n", buf); - goto err_free; - } - - p->procfs = create_proc_entry( - (video->mode == MODE_RECEIVE ? "in" : "out"), - 0666, parent->procfs); - - if (p->procfs == NULL) { - printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/%s/%s\n", - parent->name, - (video->mode == MODE_RECEIVE ? "in" : "out")); - goto err_free; - } - - p->procfs->owner = THIS_MODULE; - p->procfs->data = video; - p->procfs->read_proc = dv1394_procfs_read; - p->procfs->write_proc = dv1394_procfs_write; - - spin_lock( &dv1394_procfs_lock); - INIT_LIST_HEAD(&p->list); - list_add_tail(&p->list, &dv1394_procfs); - spin_unlock( &dv1394_procfs_lock); - - return 0; - - err_free: - kfree(p); - err: - return -ENOMEM; -} - -static int -dv1394_procfs_add_dir( char *name, - struct dv1394_procfs_entry *parent, - struct dv1394_procfs_entry **out) -{ - struct dv1394_procfs_entry *p; - - p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL); - if (!p) { - printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n"); - goto err; - } - memset(p, 0, sizeof(struct dv1394_procfs_entry)); - - if (parent == NULL) { - snprintf(p->name, sizeof(p->name), "%s", name); - p->procfs = proc_mkdir( name, ieee1394_procfs_entry); - } else { - snprintf(p->name, sizeof(p->name), "%s/%s", parent->name, name); - p->procfs = proc_mkdir( name, parent->procfs); - } - if (p->procfs == NULL) { - printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/%s\n", p->name); - goto err_free; - } - - p->procfs->owner = THIS_MODULE; - p->parent = parent; - if (out != NULL) *out = p; - - spin_lock( &dv1394_procfs_lock); - INIT_LIST_HEAD(&p->list); - list_add_tail(&p->list, &dv1394_procfs); - spin_unlock( &dv1394_procfs_lock); - - return 0; - - err_free: - kfree(p); - err: - return -ENOMEM; -} - -void dv1394_procfs_del( char *name) -{ - struct dv1394_procfs_entry *p = dv1394_procfs_find(name); - if (p != NULL) { - if (p->parent == NULL) - remove_proc_entry(p->name, ieee1394_procfs_entry); - else - remove_proc_entry(p->name, p->parent->procfs); - - spin_lock( &dv1394_procfs_lock); - list_del(&p->list); - spin_unlock( &dv1394_procfs_lock); - kfree(p); - } -} -#endif /* CONFIG_PROC_FS */ - /*** DEVICE DRIVER HANDLERS ************************************************/ static void it_tasklet_func(unsigned long data) @@ -2485,18 +2245,13 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes video->channel = 63; /* default to broadcast channel */ video->active_frame = -1; - /* initialize the following for proc_fs */ + /* initialize the following */ video->pal_or_ntsc = format; video->cip_n = 0; /* 0 = use builtin default */ video->cip_d = 0; video->syt_offset = 0; video->mode = mode; -#ifdef CONFIG_PROC_FS - if ( dv1394_procfs_add_entry(video) < 0 ) - goto err_free; -#endif - for (i = 0; i < DV1394_MAX_FRAMES; i++) video->frames[i] = NULL; @@ -2548,9 +2303,6 @@ static void dv1394_un_init(struct video_card *video) ); devfs_remove("ieee1394/%s", buf); -#ifdef CONFIG_PROC_FS - dv1394_procfs_del(buf); -#endif list_del(&video->list); kfree(video); } @@ -2562,7 +2314,6 @@ static void dv1394_remove_host (struct hpsb_host *host) struct video_card *video = NULL; unsigned long flags; struct list_head *lh, *templh; - char buf[32]; int n; /* We only work with the OHCI-1394 driver */ @@ -2588,21 +2339,11 @@ static void dv1394_remove_host (struct hpsb_host *host) devfs_remove("ieee1394/dv/host%d/NTSC", n); devfs_remove("ieee1394/dv/host%d/PAL", n); devfs_remove("ieee1394/dv/host%d", n); - -#ifdef CONFIG_PROC_FS - snprintf(buf, sizeof(buf), "dv/host%d/NTSC", n); - dv1394_procfs_del(buf); - snprintf(buf, sizeof(buf), "dv/host%d/PAL", n); - dv1394_procfs_del(buf); - snprintf(buf, sizeof(buf), "dv/host%d", n); - dv1394_procfs_del(buf); -#endif } static void dv1394_add_host (struct hpsb_host *host) { struct ti_ohci *ohci; - char buf[16]; /* We only work with the OHCI-1394 driver */ if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME)) @@ -2610,19 +2351,6 @@ static void dv1394_add_host (struct hpsb_host *host) ohci = (struct ti_ohci *)host->hostdata; -#ifdef CONFIG_PROC_FS -{ - struct dv1394_procfs_entry *p; - p = dv1394_procfs_find("dv"); - if (p != NULL) { - snprintf(buf, sizeof(buf), "host%d", ohci->id); - dv1394_procfs_add_dir(buf, p, &p); - dv1394_procfs_add_dir("NTSC", p, NULL); - dv1394_procfs_add_dir("PAL", p, NULL); - } -} -#endif - devfs_mk_dir("ieee1394/dv/host%d", ohci->id); devfs_mk_dir("ieee1394/dv/host%d/NTSC", ohci->id); devfs_mk_dir("ieee1394/dv/host%d/PAL", ohci->id); @@ -2881,9 +2609,6 @@ static void __exit dv1394_exit_module(void) hpsb_unregister_highlevel(&dv1394_highlevel); ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394); devfs_remove("ieee1394/dv"); -#ifdef CONFIG_PROC_FS - dv1394_procfs_del("dv"); -#endif } static int __init dv1394_init_module(void) @@ -2899,16 +2624,6 @@ static int __init dv1394_init_module(void) devfs_mk_dir("ieee1394/dv"); -#ifdef CONFIG_PROC_FS - ret = dv1394_procfs_add_dir("dv",NULL,NULL); - if (ret < 0) { - printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/dv\n"); - ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394); - devfs_remove("ieee1394/dv"); - return -ENOMEM; - } -#endif - hpsb_register_highlevel(&dv1394_highlevel); hpsb_register_protocol(&dv1394_driver); diff --git a/drivers/ieee1394/dv1394.h b/drivers/ieee1394/dv1394.h index d05bb555e0871..3bedfb46a42a8 100644 --- a/drivers/ieee1394/dv1394.h +++ b/drivers/ieee1394/dv1394.h @@ -1,7 +1,7 @@ /* * dv1394.h - DV input/output over IEEE 1394 on OHCI chips * Copyright (C)2001 Daniel Maas - * receive, proc_fs by Dan Dennedy + * receive by Dan Dennedy * * based on: * video1394.h - driver for OHCI 1394 boards diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 1e9ad2cc9b628..d7f025981c012 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: 986 $ Ben Collins "; + "$Rev: 1010 $ Ben Collins "; struct fragment_info { struct list_head list; @@ -1285,7 +1285,7 @@ static inline int ether1394_prep_write_packet(struct hpsb_packet *p, if (hpsb_get_tlabel(p, !in_interrupt())) { ETH1394_PRINT_G(KERN_ERR, "No more tlabels left while sending " - "to node " NODE_BUS_FMT "\n", NODE_BUS_ARGS(node)); + "to node " NODE_BUS_FMT "\n", NODE_BUS_ARGS(host, node)); return -1; } p->header[0] = (p->node_id << 16) | (p->tlabel << 10) @@ -1600,7 +1600,7 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr) case ETHTOOL_GDRVINFO: { struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; strcpy (info.driver, driver_name); - strcpy (info.version, "$Rev: 986 $"); + strcpy (info.version, "$Rev: 1010 $"); /* FIXME XXX provide sane businfo */ strcpy (info.bus_info, "ieee1394"); if (copy_to_user (useraddr, &info, sizeof (info))) diff --git a/drivers/ieee1394/highlevel.h b/drivers/ieee1394/highlevel.h index 9fd0859140fb7..584bf9f86d496 100644 --- a/drivers/ieee1394/highlevel.h +++ b/drivers/ieee1394/highlevel.h @@ -21,6 +21,7 @@ struct hpsb_address_serve { */ struct hpsb_highlevel { + struct module *owner; const char *name; /* Any of the following pointers can legally be NULL, except for diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index 8e2963455ec0d..eb5ef09b5265c 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "ieee1394_types.h" #include "hosts.h" @@ -67,7 +66,7 @@ int hpsb_ref_host(struct hpsb_host *host) list_for_each(lh, &hpsb_hosts) { if (host == list_entry(lh, struct hpsb_host, host_list)) { if (try_module_get(host->driver->owner)) { - host->refcount++; + atomic_inc(&host->refcount); retval = 1; } break; @@ -92,9 +91,7 @@ void hpsb_unref_host(struct hpsb_host *host) module_put(host->driver->owner); down(&hpsb_hosts_lock); - host->refcount--; - - if (!host->refcount && host->is_shutdown) + if (atomic_dec_and_test(&host->refcount) && host->is_shutdown) kfree(host); up(&hpsb_hosts_lock); } @@ -131,7 +128,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra) h->hostdata = h + 1; h->driver = drv; - h->refcount = 1; + atomic_set(&h->refcount, 1); INIT_LIST_HEAD(&h->pending_packets); spin_lock_init(&h->pending_pkt_lock); @@ -141,7 +138,10 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra) atomic_set(&h->generation, 0); - INIT_WORK(&h->timeout_tq, (void (*)(void*))abort_timedouts, h); + init_timer(&h->timeout); + h->timeout.data = (unsigned long) h; + h->timeout.function = abort_timedouts; + h->timeout_interval = HZ / 20; // 50ms by default h->topology_map = h->csr.topology_map + 3; h->speed_map = (u8 *)(h->csr.speed_map + 2); diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h index 7b6728c57f619..17753f8e53131 100644 --- a/drivers/ieee1394/hosts.h +++ b/drivers/ieee1394/hosts.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include "ieee1394_types.h" @@ -29,11 +29,12 @@ struct hpsb_host { atomic_t generation; - int refcount; + atomic_t refcount; struct list_head pending_packets; spinlock_t pending_pkt_lock; - struct work_struct timeout_tq; + struct timer_list timeout; + unsigned long timeout_interval; unsigned char iso_listen_count[64]; @@ -107,6 +108,7 @@ enum devctl_cmd { enum isoctl_cmd { /* rawiso API - see iso.h for the meanings of these commands + (they correspond exactly to the hpsb_iso_* API functions) * INIT = allocate resources * START = begin transmission/reception * STOP = halt transmission/reception @@ -128,6 +130,7 @@ enum isoctl_cmd { RECV_STOP, RECV_RELEASE, RECV_SHUTDOWN, + RECV_FLUSH }; enum reset_types { diff --git a/drivers/ieee1394/ieee1394-ioctl.h b/drivers/ieee1394/ieee1394-ioctl.h index 1091bdff1391f..24ef3b38af925 100644 --- a/drivers/ieee1394/ieee1394-ioctl.h +++ b/drivers/ieee1394/ieee1394-ioctl.h @@ -100,6 +100,8 @@ _IOW ('#', 0x27, struct raw1394_iso_packets) #define RAW1394_IOC_ISO_XMIT_SYNC \ _IO ('#', 0x28) +#define RAW1394_IOC_ISO_RECV_FLUSH \ + _IO ('#', 0x29) #endif /* __IEEE1394_IOCTL_H */ diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index f7034c9f63697..d9e3c09da5377 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -29,9 +29,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -62,19 +60,22 @@ static kmem_cache_t *hpsb_packet_cache; /* Some globals used */ const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" }; +#ifdef CONFIG_IEEE1394_VERBOSEDEBUG static void dump_packet(const char *text, quadlet_t *data, int size) { - int i; + int i; - size /= 4; - size = (size > 4 ? 4 : size); + size /= 4; + size = (size > 4 ? 4 : size); - printk(KERN_DEBUG "ieee1394: %s", text); - for (i = 0; i < size; i++) { - printk(" %8.8x", data[i]); - } - printk("\n"); + printk(KERN_DEBUG "ieee1394: %s", text); + for (i = 0; i < size; i++) + printk(" %08x", data[i]); + printk("\n"); } +#else +#define dump_packet(x,y,z) +#endif static void run_packet_complete(struct hpsb_packet *packet) { @@ -355,9 +356,7 @@ static void build_speed_map(struct hpsb_host *host, int nodecount) void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid) { if (host->in_bus_reset) { -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_INFO("Including SelfID 0x%x", sid); -#endif + HPSB_VERBOSE("Including SelfID 0x%x", sid); host->topology_map[host->selfid_count++] = sid; } else { HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d", @@ -384,15 +383,16 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot) } else { HPSB_NOTICE("Stopping out-of-control reset loop"); HPSB_NOTICE("Warning - topology map and speed map will not be valid"); + host->reset_retries = 0; } } else { + host->reset_retries = 0; build_speed_map(host, host->node_count); } -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_INFO("selfid_complete called with successful SelfID stage " - "... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id); -#endif + HPSB_VERBOSE("selfid_complete called with successful SelfID stage " + "... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id); + /* irm_id is kept up to date by check_selfids() */ if (host->irm_id == host->node_id) { host->is_irm = 1; @@ -440,7 +440,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, spin_unlock_irqrestore(&host->pending_pkt_lock, flags); up(&packet->state_change); - schedule_work(&host->timeout_tq); + mod_timer(&host->timeout, jiffies + host->timeout_interval); } /** @@ -550,10 +550,9 @@ int hpsb_send_packet(struct hpsb_packet *packet) } } -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG dump_packet("send packet local:", packet->header, packet->header_size); -#endif + hpsb_packet_sent(host, packet, packet->expect_response?ACK_PENDING:ACK_COMPLETE); hpsb_packet_received(host, data, size, 0); @@ -568,7 +567,6 @@ int hpsb_send_packet(struct hpsb_packet *packet) + NODEID_TO_NODE(packet->node_id)]; } -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG switch (packet->speed_code) { case 2: dump_packet("send packet 400:", packet->header, @@ -582,7 +580,6 @@ int hpsb_send_packet(struct hpsb_packet *packet) dump_packet("send packet 100:", packet->header, packet->header_size); } -#endif return host->driver->transmit_packet(host, packet); } @@ -617,7 +614,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data, } if (lh == &host->pending_packets) { - HPSB_DEBUG("unsolicited response packet received - np"); + HPSB_DEBUG("unsolicited response packet received - no tlabel match"); dump_packet("contents:", data, 16); spin_unlock_irqrestore(&host->pending_pkt_lock, flags); return; @@ -641,7 +638,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data, if (!tcode_match || (packet->tlabel != tlabel) || (packet->node_id != (data[1] >> 16))) { - HPSB_INFO("unsolicited response packet received"); + HPSB_INFO("unsolicited response packet received - tcode mismatch"); dump_packet("contents:", data, 16); spin_unlock_irqrestore(&host->pending_pkt_lock, flags); @@ -896,9 +893,7 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, return; } -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG dump_packet("received packet:", data, size); -#endif tcode = (data[0] >> 4) & 0xf; @@ -959,28 +954,23 @@ void abort_requests(struct hpsb_host *host) } } -void abort_timedouts(struct hpsb_host *host) +void abort_timedouts(unsigned long __opaque) { + struct hpsb_host *host = (struct hpsb_host *)__opaque; unsigned long flags; struct hpsb_packet *packet; unsigned long expire; - struct list_head *lh, *next, *tlh; + struct list_head *lh, *tlh; LIST_HEAD(expiredlist); spin_lock_irqsave(&host->csr.lock, flags); - expire = (host->csr.split_timeout_hi * 8000 - + (host->csr.split_timeout_lo >> 19)) - * HZ / 8000; - /* Avoid shortening of timeout due to rounding errors: */ - expire++; + expire = host->csr.expire; spin_unlock_irqrestore(&host->csr.lock, flags); - spin_lock_irqsave(&host->pending_pkt_lock, flags); - for (lh = host->pending_packets.next; lh != &host->pending_packets; lh = next) { + list_for_each_safe(lh, tlh, &host->pending_packets) { packet = list_entry(lh, struct hpsb_packet, list); - next = lh->next; if (time_before(packet->sendtime + expire, jiffies)) { list_del(&packet->list); list_add(&packet->list, &expiredlist); @@ -988,7 +978,7 @@ void abort_timedouts(struct hpsb_host *host) } if (!list_empty(&host->pending_packets)) - schedule_work(&host->timeout_tq); + mod_timer(&host->timeout, jiffies + host->timeout_interval); spin_unlock_irqrestore(&host->pending_pkt_lock, flags); @@ -1179,8 +1169,6 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file) return retval; } -struct proc_dir_entry *ieee1394_procfs_entry; - static int __init ieee1394_init(void) { hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet), @@ -1194,19 +1182,6 @@ static int __init ieee1394_init(void) return -ENODEV; } -#ifdef CONFIG_PROC_FS - /* Must be done before we start everything else, since the drivers - * may use it. */ - ieee1394_procfs_entry = proc_mkdir("ieee1394", proc_bus); - if (ieee1394_procfs_entry == NULL) { - HPSB_ERR("unable to create /proc/bus/ieee1394\n"); - unregister_chrdev(IEEE1394_MAJOR, "ieee1394"); - devfs_remove("ieee1394"); - return -ENOMEM; - } - ieee1394_procfs_entry->owner = THIS_MODULE; -#endif - init_hpsb_highlevel(); init_csr(); if (!disable_nodemgr) @@ -1227,7 +1202,6 @@ static void __exit ieee1394_cleanup(void) unregister_chrdev(IEEE1394_MAJOR, "ieee1394"); devfs_remove("ieee1394"); - remove_proc_entry("ieee1394", proc_bus); } module_init(ieee1394_init); @@ -1257,7 +1231,6 @@ EXPORT_SYMBOL(hpsb_packet_sent); EXPORT_SYMBOL(hpsb_packet_received); EXPORT_SYMBOL(ieee1394_register_chardev); EXPORT_SYMBOL(ieee1394_unregister_chardev); -EXPORT_SYMBOL(ieee1394_procfs_entry); /** ieee1394_transactions.c **/ EXPORT_SYMBOL(hpsb_get_tlabel); @@ -1341,3 +1314,4 @@ EXPORT_SYMBOL(hpsb_iso_n_ready); EXPORT_SYMBOL(hpsb_iso_packet_sent); EXPORT_SYMBOL(hpsb_iso_packet_received); EXPORT_SYMBOL(hpsb_iso_wake); +EXPORT_SYMBOL(hpsb_iso_recv_flush); diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h index b2196b21c5496..2e496d3331aac 100644 --- a/drivers/ieee1394/ieee1394_core.h +++ b/drivers/ieee1394/ieee1394_core.h @@ -4,7 +4,6 @@ #include #include -#include #include #include "hosts.h" @@ -88,7 +87,7 @@ static inline struct hpsb_packet *driver_packet(struct list_head *l) return list_entry(l, struct hpsb_packet, driver_list); } -void abort_timedouts(struct hpsb_host *host); +void abort_timedouts(unsigned long __opaque); void abort_requests(struct hpsb_host *host); struct hpsb_packet *alloc_hpsb_packet(size_t data_size); @@ -224,9 +223,6 @@ int ieee1394_register_chardev(int blocknum, /* 0-15 */ /* release a block of minor numbers */ void ieee1394_unregister_chardev(int blocknum); -/* the proc_fs entry for /proc/ieee1394 */ -extern struct proc_dir_entry *ieee1394_procfs_entry; - /* Our sysfs bus entry */ extern struct bus_type ieee1394_bus_type; diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c index 331d9de232371..72a2a2b4c1436 100644 --- a/drivers/ieee1394/ieee1394_transactions.c +++ b/drivers/ieee1394/ieee1394_transactions.c @@ -580,9 +580,7 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, u16 specifier_id_hi = (specifier_id & 0x00ffff00) >> 8; u8 specifier_id_lo = specifier_id & 0xff; -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG("Send GASP: channel = %d, length = %d", channel, length); -#endif + HPSB_VERBOSE("Send GASP: channel = %d, length = %d", channel, length); length += 8; diff --git a/drivers/ieee1394/ieee1394_types.h b/drivers/ieee1394/ieee1394_types.h index f66aadd618a0d..14f6baa92f751 100644 --- a/drivers/ieee1394/ieee1394_types.h +++ b/drivers/ieee1394/ieee1394_types.h @@ -61,8 +61,9 @@ typedef u16 arm_length_t; #define NODEID_TO_NODE(nodeid) (nodeid & NODE_MASK) /* Can be used to consistently print a node/bus ID. */ -#define NODE_BUS_FMT "%02d:%04d" -#define NODE_BUS_ARGS(nodeid) NODEID_TO_NODE(nodeid), NODEID_TO_BUS(nodeid) +#define NODE_BUS_FMT "%d-%02d:%04d" +#define NODE_BUS_ARGS(__host, __nodeid) \ + __host->id, NODEID_TO_NODE(__nodeid), NODEID_TO_BUS(__nodeid) #define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args) @@ -72,6 +73,12 @@ typedef u16 arm_length_t; #define HPSB_WARN(fmt, args...) HPSB_PRINT(KERN_WARNING, fmt , ## args) #define HPSB_ERR(fmt, args...) HPSB_PRINT(KERN_ERR, fmt , ## args) +#ifdef CONFIG_IEEE1394_VERBOSEDEBUG +#define HPSB_VERBOSE(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args) +#else +#define HPSB_VERBOSE(fmt, args...) +#endif + #define HPSB_PANIC(fmt, args...) panic("ieee1394: " fmt "\n" , ## args) #define HPSB_TRACE() HPSB_PRINT(KERN_INFO, "TRACE - %s, %s(), line %d", __FILE__, __FUNCTION__, __LINE__) diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c index ad9d9e0cc0b4c..744204d40afe8 100644 --- a/drivers/ieee1394/iso.c +++ b/drivers/ieee1394/iso.c @@ -200,6 +200,13 @@ int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask) return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask); } +int hpsb_iso_recv_flush(struct hpsb_iso *iso) +{ + if (iso->type != HPSB_ISO_RECV) + return -EINVAL; + return iso->host->driver->isoctl(iso, RECV_FLUSH, 0); +} + static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle) { int retval = iso->host->driver->isoctl(iso, XMIT_START, cycle); diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h index 2b365d4725709..c05a3574cfc82 100644 --- a/drivers/ieee1394/iso.h +++ b/drivers/ieee1394/iso.h @@ -165,6 +165,10 @@ int hpsb_iso_xmit_sync(struct hpsb_iso *iso); /* N packets have been read out of the buffer, re-use the buffer space */ int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets); +/* check for arrival of new packets immediately (even if irq_interval + has not yet been reached) */ +int hpsb_iso_recv_flush(struct hpsb_iso *iso); + /* returns # of packets ready to send or receive */ int hpsb_iso_n_ready(struct hpsb_iso *iso); diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index c8f4e8dd1641b..9898b448a6825 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -424,8 +424,15 @@ static void nodemgr_release_ne(struct device *dev) static void nodemgr_remove_ud(struct unit_directory *ud) { struct device *dev = &ud->device; + struct list_head *lh, *next; int i; + list_for_each_safe(lh, next, &ud->device.children) { + struct unit_directory *ud; + ud = container_of(list_to_dev(lh), struct unit_directory, device); + nodemgr_remove_ud(ud); + } + for (i = 0; i < ARRAY_SIZE(fw_ud_attrs); i++) device_remove_file(dev, fw_ud_attrs[i]); @@ -462,8 +469,8 @@ static void nodemgr_update_ud_names(struct host_info *hi, struct node_entry *ne) ud = container_of(list_to_dev(lh), struct unit_directory, device); snprintf(ud->device.name, DEVICE_NAME_SIZE, - "IEEE-1394 unit directory %d-" NODE_BUS_FMT "-%u", - hi->host->id, NODE_BUS_ARGS(ne->nodeid), ud->id); + "IEEE-1394 unit directory " NODE_BUS_FMT "-%u", + NODE_BUS_ARGS(hi->host, ne->nodeid), ud->id); } } @@ -714,8 +721,8 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoption snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", (unsigned long long)(ne->guid)); snprintf(ne->device.name, DEVICE_NAME_SIZE, - "IEEE-1394 device %d-" NODE_BUS_FMT, host->id, - NODE_BUS_ARGS(ne->nodeid)); + "IEEE-1394 device " NODE_BUS_FMT, + NODE_BUS_ARGS(host, ne->nodeid)); device_register(&ne->device); @@ -727,9 +734,9 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoption nodemgr_update_ud_names(hi, ne); - HPSB_DEBUG("%s added: ID:BUS[%d-" NODE_BUS_FMT "] GUID[%016Lx]", + HPSB_DEBUG("%s added: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", (host->node_id == nodeid) ? "Host" : "Node", - host->id, NODE_BUS_ARGS(nodeid), (unsigned long long)guid); + NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid); return ne; } @@ -911,7 +918,8 @@ static struct unit_directory *nodemgr_scan_unit_directory * immediate unit directories looking for software_id and * software_version entries, in order to get driver autoloading working. */ static struct unit_directory *nodemgr_process_unit_directory - (struct host_info *hi, struct node_entry *ne, octlet_t address, unsigned int *id) + (struct host_info *hi, struct node_entry *ne, octlet_t address, unsigned int *id, + struct unit_directory *parent) { struct unit_directory *ud; quadlet_t quad; @@ -1001,37 +1009,38 @@ static struct unit_directory *nodemgr_process_unit_directory break; case CONFIG_ROM_LOGICAL_UNIT_DIRECTORY: - /* TODO: Parent this with it's UD */ - ud_temp = nodemgr_process_unit_directory(hi, ne, address + value * 4, id); + ud->flags |= UNIT_DIRECTORY_HAS_LUN_DIRECTORY; + ud_temp = nodemgr_process_unit_directory(hi, ne, address + value * 4, id, + parent); + + if (ud_temp == NULL) + break; /* inherit unspecified values */ - if (ud_temp != NULL) + if ((ud->flags & UNIT_DIRECTORY_VENDOR_ID) && + !(ud_temp->flags & UNIT_DIRECTORY_VENDOR_ID)) { - if ((ud->flags & UNIT_DIRECTORY_VENDOR_ID) && - !(ud_temp->flags & UNIT_DIRECTORY_VENDOR_ID)) - { - ud_temp->flags |= UNIT_DIRECTORY_VENDOR_ID; - ud_temp->vendor_id = ud->vendor_id; - ud_temp->vendor_oui = ud->vendor_oui; - } - if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) && - !(ud_temp->flags & UNIT_DIRECTORY_MODEL_ID)) - { - ud_temp->flags |= UNIT_DIRECTORY_MODEL_ID; - ud_temp->model_id = ud->model_id; - } - if ((ud->flags & UNIT_DIRECTORY_SPECIFIER_ID) && - !(ud_temp->flags & UNIT_DIRECTORY_SPECIFIER_ID)) - { - ud_temp->flags |= UNIT_DIRECTORY_SPECIFIER_ID; - ud_temp->specifier_id = ud->specifier_id; - } - if ((ud->flags & UNIT_DIRECTORY_VERSION) && - !(ud_temp->flags & UNIT_DIRECTORY_VERSION)) - { - ud_temp->flags |= UNIT_DIRECTORY_VERSION; - ud_temp->version = ud->version; - } + ud_temp->flags |= UNIT_DIRECTORY_VENDOR_ID; + ud_temp->vendor_id = ud->vendor_id; + ud_temp->vendor_oui = ud->vendor_oui; + } + if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) && + !(ud_temp->flags & UNIT_DIRECTORY_MODEL_ID)) + { + ud_temp->flags |= UNIT_DIRECTORY_MODEL_ID; + ud_temp->model_id = ud->model_id; + } + if ((ud->flags & UNIT_DIRECTORY_SPECIFIER_ID) && + !(ud_temp->flags & UNIT_DIRECTORY_SPECIFIER_ID)) + { + ud_temp->flags |= UNIT_DIRECTORY_SPECIFIER_ID; + ud_temp->specifier_id = ud->specifier_id; + } + if ((ud->flags & UNIT_DIRECTORY_VERSION) && + !(ud_temp->flags & UNIT_DIRECTORY_VERSION)) + { + ud_temp->flags |= UNIT_DIRECTORY_VERSION; + ud_temp->version = ud->version; } break; @@ -1049,7 +1058,13 @@ static struct unit_directory *nodemgr_process_unit_directory memcpy(&ud->device, &nodemgr_dev_template_ud, sizeof(ud->device)); - ud->device.parent = &ne->device; + + if (parent) { + ud->flags |= UNIT_DIRECTORY_LUN_DIRECTORY; + ud->device.parent = &parent->device; + } else + ud->device.parent = &ne->device; + snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", ne->device.bus_id, ud->id); @@ -1125,7 +1140,8 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent break; case CONFIG_ROM_UNIT_DIRECTORY: - nodemgr_process_unit_directory(hi, ne, address + value * 4, &ud_id); + nodemgr_process_unit_directory(hi, ne, address + value * 4, &ud_id, + NULL); break; case CONFIG_ROM_DESCRIPTOR_LEAF: @@ -1239,14 +1255,13 @@ static void nodemgr_process_config_rom(struct host_info *hi, ne->busopt.generation = (busoptions >> 4) & 0xf; ne->busopt.lnkspd = busoptions & 0x7; -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d " - "cyc_clk_acc=%d max_rec=%d gen=%d lspd=%d", - busoptions, ne->busopt.irmc, ne->busopt.cmc, - ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc, - ne->busopt.cyc_clk_acc, ne->busopt.max_rec, - ne->busopt.generation, ne->busopt.lnkspd); -#endif + HPSB_VERBOSE("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d " + "cyc_clk_acc=%d max_rec=%d gen=%d lspd=%d", + busoptions, ne->busopt.irmc, ne->busopt.cmc, + ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc, + ne->busopt.cyc_clk_acc, ne->busopt.max_rec, + ne->busopt.generation, ne->busopt.lnkspd); + device_remove_file(&ne->device, &dev_attr_ne_vendor_oui); nodemgr_process_root_directory(hi, ne); @@ -1301,11 +1316,11 @@ static void nodemgr_update_node(struct node_entry *ne, quadlet_t busoptions, if (ne->nodeid != nodeid) { snprintf(ne->device.name, DEVICE_NAME_SIZE, - "IEEE-1394 device %d-" NODE_BUS_FMT, - hi->host->id, NODE_BUS_ARGS(ne->nodeid)); - HPSB_DEBUG("Node changed: %d-" NODE_BUS_FMT " -> %d-" NODE_BUS_FMT, - ne->host->id, NODE_BUS_ARGS(ne->nodeid), - ne->host->id, NODE_BUS_ARGS(nodeid)); + "IEEE-1394 device " NODE_BUS_FMT, + NODE_BUS_ARGS(hi->host, ne->nodeid)); + HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT, + NODE_BUS_ARGS(ne->host, ne->nodeid), + NODE_BUS_ARGS(ne->host, nodeid)); ne->nodeid = nodeid; update_ud_names++; @@ -1345,10 +1360,9 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned * work though, and we are forced to doing quadlet sized * reads. */ -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_INFO("Initiating ConfigROM request for node " NODE_BUS_FMT, - NODE_BUS_ARGS(nodeid)); -#endif + HPSB_VERBOSE("Initiating ConfigROM request for node " NODE_BUS_FMT, + NODE_BUS_ARGS(host, nodeid)); + /* * Must retry a few times if config rom read returns zero (how long?). Will * not normally occur, but we should do the right thing. For example, with @@ -1360,7 +1374,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned if (nodemgr_read_quadlet(host, nodeid, generation, addr, &buffer[0]) < 0) { HPSB_ERR("ConfigROM quadlet transaction error for node " - NODE_BUS_FMT, NODE_BUS_ARGS(nodeid)); + NODE_BUS_FMT, NODE_BUS_ARGS(host, nodeid)); return -1; } if (buffer[0]) @@ -1377,14 +1391,14 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned if (header_size == 1) { HPSB_INFO("Node " NODE_BUS_FMT " has a minimal ROM. " "Vendor is %08x", - NODE_BUS_ARGS(nodeid), buffer[0] & 0x00ffffff); + NODE_BUS_ARGS(host, nodeid), buffer[0] & 0x00ffffff); return -1; } if (header_size < 4) { HPSB_INFO("Node " NODE_BUS_FMT " has non-standard ROM " "format (%d quads), cannot parse", - NODE_BUS_ARGS(nodeid), header_size); + NODE_BUS_ARGS(host, nodeid), header_size); return -1; } @@ -1393,7 +1407,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned addr, &buffer[i]) < 0) { HPSB_ERR("ConfigROM quadlet transaction " "error for node " NODE_BUS_FMT, - NODE_BUS_ARGS(nodeid)); + NODE_BUS_ARGS(host, nodeid)); return -1; } } @@ -1428,7 +1442,7 @@ static void nodemgr_node_probe_one(struct host_info *hi, * shouldn't be held responsible, so we'll allow it with a * warning. */ HPSB_WARN("Node " NODE_BUS_FMT " has invalid busID magic [0x%08x]", - NODE_BUS_ARGS(nodeid), buffer[1]); + NODE_BUS_ARGS(host, nodeid), buffer[1]); } guid = ((u64)buffer[3] << 32) | buffer[4]; @@ -1508,8 +1522,8 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) nodemgr_remove_node)) { struct node_entry *ne = cleanup.ne; - HPSB_DEBUG("Node removed: ID:BUS[%d-" NODE_BUS_FMT "] GUID[%016Lx]", - host->id, NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid); + HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", + NODE_BUS_ARGS(host, ne->nodeid), (unsigned long long)ne->guid); nodemgr_remove_ne(ne); } @@ -1618,11 +1632,12 @@ static int nodemgr_host_thread(void *__hi) * happens when we get a bus reset. */ while (!down_interruptible(&hi->reset_sem) && !down_interruptible(&nodemgr_serialize)) { - unsigned int generation; + unsigned int generation = 0; int i; - /* Pause for 1/4 second, to make sure things settle down. */ - for (i = HZ/4; i > 0; i-= HZ/16) { + /* Pause for 1/4 second in 1/16 second intervals, + * to make sure things settle down. */ + for (i = 0; i < 4 ; i++) { set_current_state(TASK_INTERRUPTIBLE); if (schedule_timeout(HZ/16)) goto caught_signal; @@ -1637,7 +1652,7 @@ static int nodemgr_host_thread(void *__hi) /* If we get a reset before we are done waiting, then * start the the waiting over again */ while (!down_trylock(&hi->reset_sem)) - i = HZ/4; + i = 0; } if (!nodemgr_check_irm_capability(host, reset_cycles++)) { @@ -1658,9 +1673,7 @@ static int nodemgr_host_thread(void *__hi) } caught_signal: -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG ("NodeMgr: Exiting thread"); -#endif + HPSB_VERBOSE("NodeMgr: Exiting thread"); complete_and_exit(&hi->exited, 0); } @@ -1782,9 +1795,7 @@ static void nodemgr_host_reset(struct hpsb_host *host) struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host); if (hi != NULL) { -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - HPSB_DEBUG ("NodeMgr: Processing host reset for %s", hi->daemon_name); -#endif + HPSB_VERBOSE("NodeMgr: Processing host reset for %s", hi->daemon_name); up(&hi->reset_sem); } else HPSB_ERR ("NodeMgr: could not process reset of unused host"); diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h index f4fce32a187ac..b7c86b1e5f55d 100644 --- a/drivers/ieee1394/nodemgr.h +++ b/drivers/ieee1394/nodemgr.h @@ -82,12 +82,14 @@ struct bus_options { }; -#define UNIT_DIRECTORY_VENDOR_ID 0x01 -#define UNIT_DIRECTORY_MODEL_ID 0x02 -#define UNIT_DIRECTORY_SPECIFIER_ID 0x04 -#define UNIT_DIRECTORY_VERSION 0x08 -#define UNIT_DIRECTORY_VENDOR_TEXT 0x10 -#define UNIT_DIRECTORY_MODEL_TEXT 0x20 +#define UNIT_DIRECTORY_VENDOR_ID 0x01 +#define UNIT_DIRECTORY_MODEL_ID 0x02 +#define UNIT_DIRECTORY_SPECIFIER_ID 0x04 +#define UNIT_DIRECTORY_VERSION 0x08 +#define UNIT_DIRECTORY_VENDOR_TEXT 0x10 +#define UNIT_DIRECTORY_MODEL_TEXT 0x20 +#define UNIT_DIRECTORY_HAS_LUN_DIRECTORY 0x40 +#define UNIT_DIRECTORY_LUN_DIRECTORY 0x80 /* * A unit directory corresponds to a protocol supported by the diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 53c22dafeae94..3a31e85989c19 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -47,9 +47,6 @@ * Adam J Richter * . Use of pci_class to find device * - * Andreas Tobler - * . Updated proc_fs calls - * * Emilie Chung * . Tip on Async Request Filter * @@ -74,7 +71,6 @@ * Ben Collins * . Working big-endian support * . Updated to 2.4.x module scheme (PCI aswell) - * . Removed procfs support since it trashes random mem * . Config ROM generation * * Manfred Weihs @@ -98,6 +94,7 @@ #include #include #include +#include #include #include #include @@ -164,7 +161,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) static char version[] __devinitdata = - "$Rev: 986 $ Ben Collins "; + "$Rev: 1011 $ Ben Collins "; /* Module Parameters */ static int phys_dma = 1; @@ -502,6 +499,7 @@ static void ohci_init_config_rom(struct ti_ohci *ohci); /* Global initialization */ static void ohci_initialize(struct ti_ohci *ohci) { + char irq_buf[16]; quadlet_t buf; spin_lock_init(&ohci->phy_reg_lock); @@ -601,10 +599,15 @@ static void ohci_initialize(struct ti_ohci *ohci) reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable); buf = reg_read(ohci, OHCI1394_Version); - PRINT(KERN_INFO, ohci->id, "OHCI-1394 %d.%d (PCI): IRQ=[%d] " +#ifndef __sparc__ + sprintf (irq_buf, "%d", ohci->dev->irq); +#else + sprintf (irq_buf, "%s", __irq_itoa(ohci->dev->irq)); +#endif + PRINT(KERN_INFO, ohci->id, "OHCI-1394 %d.%d (PCI): IRQ=[%s] " "MMIO=[%lx-%lx] Max Packet=[%d]", ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10), - ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), ohci->dev->irq, + ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf, pci_resource_start(ohci->dev, 0), pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1, ohci->max_packet_size); @@ -625,7 +628,7 @@ static void insert_packet(struct ti_ohci *ohci, DBGMSG(ohci->id, "Inserting packet for node " NODE_BUS_FMT ", tlabel=%d, tcode=0x%x, speed=%d", - NODE_BUS_ARGS(packet->node_id), packet->tlabel, + NODE_BUS_ARGS(ohci->host, packet->node_id), packet->tlabel, packet->tcode, packet->speed_code); d->prg_cpu[idx]->begin.address = 0; @@ -650,8 +653,8 @@ static void insert_packet(struct ti_ohci *ohci, if (packet->type == hpsb_raw) { d->prg_cpu[idx]->data[0] = cpu_to_le32(OHCI1394_TCODE_PHY<<4); - d->prg_cpu[idx]->data[1] = packet->header[0]; - d->prg_cpu[idx]->data[2] = packet->header[1]; + d->prg_cpu[idx]->data[1] = cpu_to_le32(packet->header[0]); + d->prg_cpu[idx]->data[2] = cpu_to_le32(packet->header[1]); } else { d->prg_cpu[idx]->data[0] = packet->speed_code<<16 | (packet->header[0] & 0xFFFF); @@ -1146,8 +1149,7 @@ struct ohci_iso_recv { u32 ContextMatch; }; -static void ohci_iso_recv_bufferfill_task(unsigned long data); -static void ohci_iso_recv_packetperbuf_task(unsigned long data); +static void ohci_iso_recv_task(unsigned long data); static void ohci_iso_recv_stop(struct hpsb_iso *iso); static void ohci_iso_recv_shutdown(struct hpsb_iso *iso); static int ohci_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync); @@ -1237,10 +1239,7 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso) ohci1394_init_iso_tasklet(&recv->task, iso->channel == -1 ? OHCI_ISO_MULTICHANNEL_RECEIVE : OHCI_ISO_RECEIVE, - recv->dma_mode == BUFFER_FILL_MODE ? - ohci_iso_recv_bufferfill_task : - ohci_iso_recv_packetperbuf_task, - (unsigned long) iso); + ohci_iso_recv_task, (unsigned long) iso); if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) goto err; @@ -1665,18 +1664,14 @@ static void ohci_iso_recv_bufferfill_parse(struct hpsb_iso *iso, struct ohci_iso hpsb_iso_wake(iso); } -static void ohci_iso_recv_bufferfill_task(unsigned long data) +static void ohci_iso_recv_bufferfill_task(struct hpsb_iso *iso, struct ohci_iso_recv *recv) { - struct hpsb_iso *iso = (struct hpsb_iso*) data; - struct ohci_iso_recv *recv = iso->hostdata; - int loop; /* loop over all blocks */ for (loop = 0; loop < recv->nblocks; loop++) { /* check block_dma to see if it's done */ - struct dma_cmd *im = &recv->block[recv->block_dma]; /* check the DMA descriptor for new writes to xferStatus */ @@ -1726,10 +1721,8 @@ static void ohci_iso_recv_bufferfill_task(unsigned long data) ohci_iso_recv_bufferfill_parse(iso, recv); } -static void ohci_iso_recv_packetperbuf_task(unsigned long data) +static void ohci_iso_recv_packetperbuf_task(struct hpsb_iso *iso, struct ohci_iso_recv *recv) { - struct hpsb_iso *iso = (struct hpsb_iso*) data; - struct ohci_iso_recv *recv = iso->hostdata; int count; int wake = 0; @@ -1803,6 +1796,16 @@ out: hpsb_iso_wake(iso); } +static void ohci_iso_recv_task(unsigned long data) +{ + struct hpsb_iso *iso = (struct hpsb_iso*) data; + struct ohci_iso_recv *recv = iso->hostdata; + + if (recv->dma_mode == BUFFER_FILL_MODE) + ohci_iso_recv_bufferfill_task(iso, recv); + else + ohci_iso_recv_packetperbuf_task(iso, recv); +} /*********************************** * rawiso ISO transmission * @@ -2125,6 +2128,9 @@ static int ohci_isoctl(struct hpsb_iso *iso, enum isoctl_cmd cmd, unsigned long case RECV_RELEASE: ohci_iso_recv_release(iso, (struct hpsb_iso_packet_info*) arg); return 0; + case RECV_FLUSH: + ohci_iso_recv_task((unsigned long) iso); + return 0; case RECV_SHUTDOWN: ohci_iso_recv_shutdown(iso); return 0; @@ -3465,7 +3471,31 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) case OHCI_INIT_DONE: hpsb_remove_host(ohci->host); + /* Clear out BUS Options */ + reg_write(ohci, OHCI1394_ConfigROMhdr, 0); + reg_write(ohci, OHCI1394_BusOptions, + (reg_read(ohci, OHCI1394_BusOptions) & 0x0000f007) | + 0x00ff0000); + memset(ohci->csr_config_rom_cpu, 0, OHCI_CONFIG_ROM_LEN); + case OHCI_INIT_HAVE_IRQ: + /* Clear interrupt registers */ + reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff); + reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff); + reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff); + reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff); + reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff); + reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff); + + /* Disable IRM Contender */ + set_phy_reg(ohci, 4, ~0xc0 & get_phy_reg(ohci, 4)); + + /* Clear link control register */ + reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff); + + /* Let all other nodes know to ignore us */ + ohci_devctl(ohci->host, RESET_BUS, LONG_RESET_NO_FORCE_ROOT); + /* Soft reset before we start - this disables * interrupts and clears linkEnable and LPS. */ ohci_soft_reset(ohci); diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c index d1a707c2cfc47..7efa1db813979 100644 --- a/drivers/ieee1394/pcilynx.c +++ b/drivers/ieee1394/pcilynx.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -1457,6 +1458,14 @@ static void remove_card(struct pci_dev *dev) case have_intr: reg_write(lynx, PCI_INT_ENABLE, 0); free_irq(lynx->dev->irq, lynx); + + /* Disable IRM Contender */ + if (lynx->phyic.reg_1394a) + set_phy_reg(lynx, 4, ~0xc0 & get_phy_reg(lynx, 4)); + + /* Let all other nodes know to ignore us */ + lynx_devctl(lynx->host, RESET_BUS, LONG_RESET_NO_FORCE_ROOT); + case have_iomappings: reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET); /* Fix buggy cards with autoboot pin not tied low: */ @@ -1504,6 +1513,7 @@ static int __devinit add_card(struct pci_dev *dev, return error; \ } while (0) + char irq_buf[16]; struct hpsb_host *host; struct ti_lynx *lynx; /* shortcut to currently handled device */ struct ti_pcl pcl; @@ -1603,12 +1613,18 @@ static int __devinit add_card(struct pci_dev *dev, /* Fix buggy cards with autoboot pin not tied low: */ reg_write(lynx, DMA0_CHAN_CTRL, 0); +#ifndef __sparc__ + sprintf (irq_buf, "%d", dev->irq); +#else + sprintf (irq_buf, "%s", __irq_itoa(dev->irq)); +#endif + if (!request_irq(dev->irq, lynx_irq_handler, SA_SHIRQ, PCILYNX_DRIVER_NAME, lynx)) { - PRINT(KERN_INFO, lynx->id, "allocated interrupt %d", dev->irq); + PRINT(KERN_INFO, lynx->id, "allocated interrupt %s", irq_buf); lynx->state = have_intr; } else { - FAIL("failed to allocate shared interrupt %d", dev->irq); + FAIL("failed to allocate shared interrupt %s", irq_buf); } /* alloc_pcl return values are not checked, it is expected that the @@ -1787,9 +1803,8 @@ static int __devinit add_card(struct pci_dev *dev, i2c_adapter.algo_data = &i2c_adapter_data; i2c_adapter_data.data = lynx; -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - PRINT(KERN_DEBUG, lynx->id,"original eeprom control: %d",reg_read(lynx,SERIAL_EEPROM_CONTROL)); -#endif + PRINTD(KERN_DEBUG, lynx->id,"original eeprom control: %d", + reg_read(lynx, SERIAL_EEPROM_CONTROL)); /* reset hardware to sane state */ lynx->i2c_driven_state = 0x00000070; @@ -1832,17 +1847,16 @@ static int __devinit add_card(struct pci_dev *dev, if (i2c_transfer(&i2c_adapter, msg, 2) < 0) { PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c"); } else { -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG int i; -#endif + PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom"); - /* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a), generation(1394a) and link_spd(1394a) field - and recalculate the CRC */ + /* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a), + * generation(1394a) and link_spd(1394a) field and recalculate + * the CRC */ -#ifdef CONFIG_IEEE1394_VERBOSEDEBUG - for (i=0; i < 5 ; i++) - PRINT(KERN_DEBUG, lynx->id, "Businfo block quadlet %i: %08x",i, be32_to_cpu(lynx->config_rom[i])); -#endif + for (i = 0; i < 5 ; i++) + PRINTD(KERN_DEBUG, lynx->id, "Businfo block quadlet %i: %08x", + i, be32_to_cpu(lynx->config_rom[i])); /* info_length, crc_length and 1394 magic number to check, if it is really a bus info block */ if (((be32_to_cpu(lynx->config_rom[0]) & 0xffff0000) == 0x04040000) && diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 5c3f74e46fc08..b6f734ce9cc57 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -1566,8 +1566,8 @@ static int arm_register(struct file_info *fi, struct pending_request *req) req->req.length, ((req->req.misc >> 8) & 0xFF), (req->req.misc & 0xFF),((req->req.misc >> 16) & 0xFFFF)); /* check addressrange */ - if ((((req->req.address) & ~(0xFFFFFFFFFFFF)) != 0) || - (((req->req.address + req->req.length) & ~(0xFFFFFFFFFFFF)) != 0)) { + if ((((req->req.address) & ~((u64)0xFFFFFFFFFFFFLL)) != 0) || + (((req->req.address + req->req.length) & ~((u64)0xFFFFFFFFFFFFLL)) != 0)) { req->req.length = 0; return (-EINVAL); } @@ -2273,6 +2273,8 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm return raw1394_iso_recv_packets(fi, (void*) arg); case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS: return hpsb_iso_recv_release_packets(fi->iso_handle, arg); + case RAW1394_IOC_ISO_RECV_FLUSH: + return hpsb_iso_recv_flush(fi->iso_handle); case RAW1394_IOC_ISO_SHUTDOWN: raw1394_iso_shutdown(fi); return 0; diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index e56e9b25b6a9e..a17bf9e96c80f 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -81,7 +80,7 @@ #include "sbp2.h" static char version[] __devinitdata = - "$Rev: 967 $ Ben Collins "; + "$Rev: 1010 $ Ben Collins "; /* * Module load parameter definitions @@ -611,6 +610,11 @@ static int sbp2_probe(struct device *dev) ud = container_of(dev, struct unit_directory, device); + /* Don't probe UD's that have the LUN flag. We'll probe the LUN(s) + * instead. */ + if (ud->flags & UNIT_DIRECTORY_HAS_LUN_DIRECTORY) + return -ENODEV; + /* This will only add it if it doesn't exist */ hi = sbp2_add_host(ud->ne->host); @@ -1142,7 +1146,7 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) SBP2_DEBUG("sbp2_query_logins: orb byte-swapped"); - sbp2util_packet_dump(scsi_id->query_logins_orb, sizeof(stuct sbp2_query_logins_orb), + sbp2util_packet_dump(scsi_id->query_logins_orb, sizeof(struct sbp2_query_logins_orb), "sbp2 query logins orb", scsi_id->query_logins_orb_dma); memset(scsi_id->query_logins_response, 0, sizeof(struct sbp2_query_logins_response)); @@ -1620,7 +1624,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group, SBP2_128KB_BROKEN_FIRMWARE && (max_sectors * 512) > (128*1024)) { SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB max transfer size.", - NODE_BUS_ARGS(ud->ne->nodeid)); + NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid)); SBP2_WARN("WARNING: Current max_sectors setting is larger than 128KB (%d sectors)!", max_sectors); workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER; @@ -1633,36 +1637,44 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group, if ((firmware_revision & 0xffff00) == sbp2_broken_inquiry_list[i]) { SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround", - NODE_BUS_ARGS(ud->ne->nodeid)); + NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid)); workarounds |= SBP2_BREAKAGE_INQUIRY_HACK; break; /* No need to continue. */ } } - /* If our list is empty, add a base scsi_id (happens in a normal - * case where there is no logical_unit_number entry */ - if (list_empty(&scsi_group->scsi_id_list)) { - scsi_id = kmalloc(sizeof(*scsi_id), GFP_KERNEL); - if (!scsi_id) { - SBP2_ERR("Out of memory adding scsi_id"); - return; - } - memset(scsi_id, 0, sizeof(*scsi_id)); + /* If this is a logical unit directory entry, process the parent + * to get the common values. */ + if (ud->flags & UNIT_DIRECTORY_LUN_DIRECTORY) { + struct unit_directory *parent_ud = + container_of(ud->device.parent, struct unit_directory, device); + sbp2_parse_unit_directory(scsi_group, parent_ud); + } else { + /* If our list is empty, add a base scsi_id (happens in a normal + * case where there is no logical_unit_number entry */ + if (list_empty(&scsi_group->scsi_id_list)) { + scsi_id = kmalloc(sizeof(*scsi_id), GFP_KERNEL); + if (!scsi_id) { + SBP2_ERR("Out of memory adding scsi_id"); + return; + } + memset(scsi_id, 0, sizeof(*scsi_id)); - scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED; - list_add_tail(&scsi_id->list, &scsi_group->scsi_id_list); - } + scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED; + list_add_tail(&scsi_id->list, &scsi_group->scsi_id_list); + } - /* Update the generic fields in all the LUN's */ - list_for_each (lh, &scsi_group->scsi_id_list) { - scsi_id = list_entry(lh, struct scsi_id_instance_data, list); + /* Update the generic fields in all the LUN's */ + list_for_each (lh, &scsi_group->scsi_id_list) { + scsi_id = list_entry(lh, struct scsi_id_instance_data, list); - scsi_id->sbp2_management_agent_addr = management_agent_addr; - scsi_id->sbp2_command_set_spec_id = command_set_spec_id; - scsi_id->sbp2_command_set = command_set; - scsi_id->sbp2_unit_characteristics = unit_characteristics; - scsi_id->sbp2_firmware_revision = firmware_revision; - scsi_id->workarounds = workarounds; + scsi_id->sbp2_management_agent_addr = management_agent_addr; + scsi_id->sbp2_command_set_spec_id = command_set_spec_id; + scsi_id->sbp2_command_set = command_set; + scsi_id->sbp2_unit_characteristics = unit_characteristics; + scsi_id->sbp2_firmware_revision = firmware_revision; + scsi_id->workarounds = workarounds; + } } } @@ -1697,8 +1709,9 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id) scsi_id->max_payload_size = min(sbp2_speedto_max_payload[scsi_id->speed_code], (u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1)); - SBP2_ERR("Node[" NODE_BUS_FMT "]: Max speed [%s] - Max payload [%u]", - NODE_BUS_ARGS(scsi_id->ne->nodeid), hpsb_speedto_str[scsi_id->speed_code], + SBP2_ERR("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [%u]", + NODE_BUS_ARGS(hi->host, scsi_id->ne->nodeid), + hpsb_speedto_str[scsi_id->speed_code], 1 << ((u32)scsi_id->max_payload_size + 2)); return(0); @@ -2845,70 +2858,6 @@ static const char *sbp2scsi_info (struct Scsi_Host *host) return "SCSI emulation for IEEE-1394 SBP-2 Devices"; } -/* Called for contents of procfs */ -#define SPRINTF(args...) \ - do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) - -static int sbp2scsi_proc_info(struct Scsi_Host *scsi_host, char *buffer, char **start, off_t offset, - int length, int inout) -{ - Scsi_Device *scd; - struct hpsb_host *host; - char *pos = buffer; - - /* if someone is sending us data, just throw it away */ - if (inout) - return length; - - host = hpsb_get_host_bykey(&sbp2_highlevel, (unsigned long)scsi_host); - if (!host) /* shouldn't happen, but... */ - return -ESRCH; - - SPRINTF("Host scsi%d : SBP-2 IEEE-1394 (%s)\n", - scsi_host->host_no, host->driver->name); - SPRINTF("Driver version : %s\n", version); - - SPRINTF("\nModule options :\n"); - SPRINTF(" max_speed : %s\n", hpsb_speedto_str[max_speed]); - SPRINTF(" max_sectors : %d\n", max_sectors); - SPRINTF(" serialize_io : %s\n", serialize_io ? "yes" : "no"); - SPRINTF(" exclusive_login : %s\n", exclusive_login ? "yes" : "no"); - - SPRINTF("\nAttached devices : %s\n", !list_empty(&scsi_host->my_devices) ? - "" : "none"); - - list_for_each_entry (scd, &scsi_host->my_devices, siblings) { - int i; - - SPRINTF(" [Channel: %02d, Id: %02d, Lun: %02d] ", scd->channel, - scd->id, scd->lun); - SPRINTF("%s ", (scd->type < MAX_SCSI_DEVICE_CODE) ? - scsi_device_types[(short) scd->type] : "Unknown device"); - - for (i = 0; (i < 8) && (scd->vendor[i] >= 0x20); i++) - SPRINTF("%c", scd->vendor[i]); - - SPRINTF(" "); - - for (i = 0; (i < 16) && (scd->model[i] >= 0x20); i++) - SPRINTF("%c", scd->model[i]); - - SPRINTF("\n"); - } - - SPRINTF("\n"); - - /* Calculate start of next buffer, and return value. */ - *start = buffer + offset; - - if ((pos - buffer) < offset) - return (0); - else if ((pos - buffer - offset) < length) - return (pos - buffer - offset); - else - return (length); -} - MODULE_AUTHOR("Ben Collins "); MODULE_DESCRIPTION("IEEE-1394 SBP-2 protocol driver"); MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME); @@ -2920,7 +2869,6 @@ static Scsi_Host_Template scsi_driver_template = { .name = "SBP-2 IEEE-1394", .proc_name = SBP2_DEVICE_NAME, .info = sbp2scsi_info, - .proc_info = sbp2scsi_proc_info, .queuecommand = sbp2scsi_queuecommand, .eh_abort_handler = sbp2scsi_abort, .eh_device_reset_handler = sbp2scsi_reset, @@ -2939,6 +2887,8 @@ static int sbp2_module_init(void) { SBP2_DEBUG("sbp2_module_init"); + printk(KERN_INFO "sbp2: %s\n", version); + /* Module load debug option to force one command at a time (serializing I/O) */ if (serialize_io) { SBP2_ERR("Driver forced to serialize I/O (serialize_io = 1)"); diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 25c02ec2bd58c..112b1b89593bb 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include -- 2.53.0