diff --git a/[refs] b/[refs] index c610936e5f11..26a7524f32ee 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0a75c23a009ff65f651532cecc16675d05f4de37 +refs/heads/master: 4ffd2e4907184813101cefa7196102927cdbe104 diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 8ae8dad8e150..9b743198f77a 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -47,6 +47,17 @@ Who: Paul E. McKenney --------------------------- +What: IEEE1394 Audio and Music Data Transmission Protocol driver, + Connection Management Procedures driver +When: November 2005 +Files: drivers/ieee1394/{amdtp,cmp}* +Why: These are incomplete, have never worked, and are better implemented + in userland via raw1394 (see http://freebob.sourceforge.net/ for + example.) +Who: Jody McIntyre + +--------------------------- + What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN When: November 2005 Why: Deprecated in favour of the new ioctl-based rawiso interface, which is diff --git a/trunk/drivers/ieee1394/Kconfig b/trunk/drivers/ieee1394/Kconfig index 39142e2f804b..25103a0ef9b3 100644 --- a/trunk/drivers/ieee1394/Kconfig +++ b/trunk/drivers/ieee1394/Kconfig @@ -169,4 +169,27 @@ config IEEE1394_RAWIO To compile this driver as a module, say M here: the module will be called raw1394. +config IEEE1394_CMP + tristate "IEC61883-1 Plug support" + depends on IEEE1394 + help + This option enables the Connection Management Procedures + (IEC61883-1) driver, which implements input and output plugs. + + To compile this driver as a module, say M here: the + module will be called cmp. + +config IEEE1394_AMDTP + tristate "IEC61883-6 (Audio transmission) support" + depends on IEEE1394 && IEEE1394_OHCI1394 && IEEE1394_CMP + help + This option enables the Audio & Music Data Transmission Protocol + (IEC61883-6) driver, which implements audio transmission over + IEEE1394. + + The userspace interface is documented in amdtp.h. + + To compile this driver as a module, say M here: the + module will be called amdtp. + endmenu diff --git a/trunk/drivers/ieee1394/Makefile b/trunk/drivers/ieee1394/Makefile index 6f53611fe255..e8b4d48d376e 100644 --- a/trunk/drivers/ieee1394/Makefile +++ b/trunk/drivers/ieee1394/Makefile @@ -14,6 +14,8 @@ obj-$(CONFIG_IEEE1394_RAWIO) += raw1394.o obj-$(CONFIG_IEEE1394_SBP2) += sbp2.o obj-$(CONFIG_IEEE1394_DV1394) += dv1394.o obj-$(CONFIG_IEEE1394_ETH1394) += eth1394.o +obj-$(CONFIG_IEEE1394_AMDTP) += amdtp.o +obj-$(CONFIG_IEEE1394_CMP) += cmp.o quiet_cmd_oui2c = OUI2C $@ cmd_oui2c = $(CONFIG_SHELL) $(srctree)/$(src)/oui2c.sh < $< > $@ diff --git a/trunk/drivers/ieee1394/csr1212.c b/trunk/drivers/ieee1394/csr1212.c index 15773544234b..61ddd5d37eff 100644 --- a/trunk/drivers/ieee1394/csr1212.c +++ b/trunk/drivers/ieee1394/csr1212.c @@ -1261,7 +1261,7 @@ static int csr1212_parse_bus_info_block(struct csr1212_csr *csr) return CSR1212_EINVAL; #endif - cr = CSR1212_MALLOC(sizeof(*cr)); + cr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region)); if (!cr) return CSR1212_ENOMEM; @@ -1393,7 +1393,8 @@ int csr1212_parse_keyval(struct csr1212_keyval *kv, case CSR1212_KV_TYPE_LEAF: if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) { kv->value.leaf.data = CSR1212_MALLOC(quads_to_bytes(kvi_len)); - if (!kv->value.leaf.data) { + if (!kv->value.leaf.data) + { ret = CSR1212_ENOMEM; goto fail; } @@ -1461,7 +1462,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv) cache->next = NULL; csr->cache_tail = cache; cache->filled_head = - CSR1212_MALLOC(sizeof(*cache->filled_head)); + CSR1212_MALLOC(sizeof(struct csr1212_cache_region)); if (!cache->filled_head) { return CSR1212_ENOMEM; } @@ -1483,7 +1484,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv) /* Now seach read portions of the cache to see if it is there. */ for (cr = cache->filled_head; cr; cr = cr->next) { if (cache_index < cr->offset_start) { - newcr = CSR1212_MALLOC(sizeof(*newcr)); + newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region)); if (!newcr) return CSR1212_ENOMEM; @@ -1507,7 +1508,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv) if (!cr) { cr = cache->filled_tail; - newcr = CSR1212_MALLOC(sizeof(*newcr)); + newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region)); if (!newcr) return CSR1212_ENOMEM; @@ -1610,17 +1611,15 @@ int csr1212_parse_csr(struct csr1212_csr *csr) csr->root_kv->valid = 0; csr->root_kv->next = csr->root_kv; csr->root_kv->prev = csr->root_kv; - ret = _csr1212_read_keyval(csr, csr->root_kv); - if (ret != CSR1212_SUCCESS) - return ret; + csr1212_get_keyval(csr, csr->root_kv); /* Scan through the Root directory finding all extended ROM regions * and make cache regions for them */ for (dentry = csr->root_kv->value.directory.dentries_head; dentry; dentry = dentry->next) { - if (dentry->kv->key.id == CSR1212_KV_ID_EXTENDED_ROM && - !dentry->kv->valid) { - ret = _csr1212_read_keyval(csr, dentry->kv); + if (dentry->kv->key.id == CSR1212_KV_ID_EXTENDED_ROM) { + csr1212_get_keyval(csr, dentry->kv); + if (ret != CSR1212_SUCCESS) return ret; } diff --git a/trunk/drivers/ieee1394/csr1212.h b/trunk/drivers/ieee1394/csr1212.h index cecd5871f2de..28c5f4b726e2 100644 --- a/trunk/drivers/ieee1394/csr1212.h +++ b/trunk/drivers/ieee1394/csr1212.h @@ -646,7 +646,7 @@ static inline struct csr1212_csr_rom_cache *csr1212_rom_cache_malloc(u_int32_t o { struct csr1212_csr_rom_cache *cache; - cache = CSR1212_MALLOC(sizeof(*cache) + size); + cache = CSR1212_MALLOC(sizeof(struct csr1212_csr_rom_cache) + size); if (!cache) return NULL; diff --git a/trunk/drivers/ieee1394/dma.c b/trunk/drivers/ieee1394/dma.c index 9fb2769d9abc..b79ddb43e746 100644 --- a/trunk/drivers/ieee1394/dma.c +++ b/trunk/drivers/ieee1394/dma.c @@ -23,8 +23,7 @@ void dma_prog_region_init(struct dma_prog_region *prog) prog->bus_addr = 0; } -int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, - struct pci_dev *dev) +int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev) { /* round up to page size */ n_bytes = PAGE_ALIGN(n_bytes); @@ -33,8 +32,7 @@ int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, prog->kvirt = pci_alloc_consistent(dev, n_bytes, &prog->bus_addr); if (!prog->kvirt) { - printk(KERN_ERR - "dma_prog_region_alloc: pci_alloc_consistent() failed\n"); + printk(KERN_ERR "dma_prog_region_alloc: pci_alloc_consistent() failed\n"); dma_prog_region_free(prog); return -ENOMEM; } @@ -47,8 +45,7 @@ int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, void dma_prog_region_free(struct dma_prog_region *prog) { if (prog->kvirt) { - pci_free_consistent(prog->dev, prog->n_pages << PAGE_SHIFT, - prog->kvirt, prog->bus_addr); + pci_free_consistent(prog->dev, prog->n_pages << PAGE_SHIFT, prog->kvirt, prog->bus_addr); } prog->kvirt = NULL; @@ -68,8 +65,7 @@ void dma_region_init(struct dma_region *dma) dma->sglist = NULL; } -int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, - struct pci_dev *dev, int direction) +int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_dev *dev, int direction) { unsigned int i; @@ -99,16 +95,14 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, /* fill scatter/gather list with pages */ for (i = 0; i < dma->n_pages; i++) { - unsigned long va = - (unsigned long)dma->kvirt + (i << PAGE_SHIFT); + unsigned long va = (unsigned long) dma->kvirt + (i << PAGE_SHIFT); dma->sglist[i].page = vmalloc_to_page((void *)va); dma->sglist[i].length = PAGE_SIZE; } /* map sglist to the IOMMU */ - dma->n_dma_pages = - pci_map_sg(dev, dma->sglist, dma->n_pages, direction); + dma->n_dma_pages = pci_map_sg(dev, dma->sglist, dma->n_pages, direction); if (dma->n_dma_pages == 0) { printk(KERN_ERR "dma_region_alloc: pci_map_sg() failed\n"); @@ -120,7 +114,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, return 0; - err: +err: dma_region_free(dma); return -ENOMEM; } @@ -128,8 +122,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, void dma_region_free(struct dma_region *dma) { if (dma->n_dma_pages) { - pci_unmap_sg(dma->dev, dma->sglist, dma->n_pages, - dma->direction); + pci_unmap_sg(dma->dev, dma->sglist, dma->n_pages, dma->direction); dma->n_dma_pages = 0; dma->dev = NULL; } @@ -144,8 +137,7 @@ void dma_region_free(struct dma_region *dma) /* find the scatterlist index and remaining offset corresponding to a given offset from the beginning of the buffer */ -static inline int dma_region_find(struct dma_region *dma, unsigned long offset, - unsigned long *rem) +static inline int dma_region_find(struct dma_region *dma, unsigned long offset, unsigned long *rem) { int i; unsigned long off = offset; @@ -164,18 +156,15 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset, return i; } -dma_addr_t dma_region_offset_to_bus(struct dma_region * dma, - unsigned long offset) +dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset) { unsigned long rem = 0; - struct scatterlist *sg = - &dma->sglist[dma_region_find(dma, offset, &rem)]; + struct scatterlist *sg = &dma->sglist[dma_region_find(dma, offset, &rem)]; return sg_dma_address(sg) + rem; } -void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset, - unsigned long len) +void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset, unsigned long len) { int first, last; unsigned long rem; @@ -186,12 +175,10 @@ void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset, first = dma_region_find(dma, offset, &rem); last = dma_region_find(dma, offset + len - 1, &rem); - pci_dma_sync_sg_for_cpu(dma->dev, &dma->sglist[first], last - first + 1, - dma->direction); + pci_dma_sync_sg_for_cpu(dma->dev, &dma->sglist[first], last - first + 1, dma->direction); } -void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset, - unsigned long len) +void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset, unsigned long len) { int first, last; unsigned long rem; @@ -202,47 +189,44 @@ void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset, first = dma_region_find(dma, offset, &rem); last = dma_region_find(dma, offset + len - 1, &rem); - pci_dma_sync_sg_for_device(dma->dev, &dma->sglist[first], - last - first + 1, dma->direction); + pci_dma_sync_sg_for_device(dma->dev, &dma->sglist[first], last - first + 1, dma->direction); } #ifdef CONFIG_MMU /* nopage() handler for mmap access */ -static struct page *dma_region_pagefault(struct vm_area_struct *area, - unsigned long address, int *type) +static struct page* +dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int *type) { unsigned long offset; unsigned long kernel_virt_addr; struct page *ret = NOPAGE_SIGBUS; - struct dma_region *dma = (struct dma_region *)area->vm_private_data; + struct dma_region *dma = (struct dma_region*) area->vm_private_data; if (!dma->kvirt) goto out; - if ((address < (unsigned long)area->vm_start) || - (address > - (unsigned long)area->vm_start + (dma->n_pages << PAGE_SHIFT))) + if ( (address < (unsigned long) area->vm_start) || + (address > (unsigned long) area->vm_start + (dma->n_pages << PAGE_SHIFT)) ) goto out; if (type) *type = VM_FAULT_MINOR; offset = address - area->vm_start; - kernel_virt_addr = (unsigned long)dma->kvirt + offset; - ret = vmalloc_to_page((void *)kernel_virt_addr); + kernel_virt_addr = (unsigned long) dma->kvirt + offset; + ret = vmalloc_to_page((void*) kernel_virt_addr); get_page(ret); - out: +out: return ret; } static struct vm_operations_struct dma_region_vm_ops = { - .nopage = dma_region_pagefault, + .nopage = dma_region_pagefault, }; -int dma_region_mmap(struct dma_region *dma, struct file *file, - struct vm_area_struct *vma) +int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma) { unsigned long size; @@ -266,12 +250,11 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, return 0; } -#else /* CONFIG_MMU */ +#else /* CONFIG_MMU */ -int dma_region_mmap(struct dma_region *dma, struct file *file, - struct vm_area_struct *vma) +int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma) { return -EINVAL; } -#endif /* CONFIG_MMU */ +#endif /* CONFIG_MMU */ diff --git a/trunk/drivers/ieee1394/dv1394.c b/trunk/drivers/ieee1394/dv1394.c index 196db7439272..cbbbe14b8849 100644 --- a/trunk/drivers/ieee1394/dv1394.c +++ b/trunk/drivers/ieee1394/dv1394.c @@ -123,6 +123,15 @@ #include "ohci1394.h" +#ifndef virt_to_page +#define virt_to_page(x) MAP_NR(x) +#endif + +#ifndef vmalloc_32 +#define vmalloc_32(x) vmalloc(x) +#endif + + /* DEBUG LEVELS: 0 - no debugging messages 1 - some debugging messages, but none during DMA frame transmission @@ -2209,12 +2218,14 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes unsigned long flags; int i; - video = kzalloc(sizeof(*video), GFP_KERNEL); + video = kmalloc(sizeof(struct video_card), GFP_KERNEL); if (!video) { printk(KERN_ERR "dv1394: cannot allocate video_card\n"); goto err; } + memset(video, 0, sizeof(struct video_card)); + video->ohci = ohci; /* lower 2 bits of id indicate which of four "plugs" per host */ diff --git a/trunk/drivers/ieee1394/eth1394.c b/trunk/drivers/ieee1394/eth1394.c index 30fa0d43a43a..c9e92d85c893 100644 --- a/trunk/drivers/ieee1394/eth1394.c +++ b/trunk/drivers/ieee1394/eth1394.c @@ -88,6 +88,9 @@ printk(KERN_ERR "%s:%s[%d]: " fmt "\n", driver_name, __FUNCTION__, __LINE__, ## args) #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) +static char version[] __devinitdata = + "$Rev: 1312 $ Ben Collins "; + struct fragment_info { struct list_head list; int offset; @@ -352,12 +355,12 @@ static int eth1394_probe(struct device *dev) if (!hi) return -ENOENT; - new_node = kmalloc(sizeof(*new_node), + new_node = kmalloc(sizeof(struct eth1394_node_ref), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); if (!new_node) return -ENOMEM; - node_info = kmalloc(sizeof(*node_info), + node_info = kmalloc(sizeof(struct eth1394_node_info), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); if (!node_info) { kfree(new_node); @@ -433,12 +436,12 @@ static int eth1394_update(struct unit_directory *ud) node = eth1394_find_node(&priv->ip_node_list, ud); if (!node) { - node = kmalloc(sizeof(*node), + node = kmalloc(sizeof(struct eth1394_node_ref), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); if (!node) return -ENOMEM; - node_info = kmalloc(sizeof(*node_info), + node_info = kmalloc(sizeof(struct eth1394_node_info), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); if (!node_info) { kfree(node); @@ -563,6 +566,7 @@ static void ether1394_add_host (struct hpsb_host *host) struct eth1394_host_info *hi = NULL; struct net_device *dev = NULL; struct eth1394_priv *priv; + static int version_printed = 0; u64 fifo_addr; if (!(host->config_roms & HPSB_CONFIG_ROM_ENTRY_IP1394)) @@ -577,6 +581,9 @@ static void ether1394_add_host (struct hpsb_host *host) if (fifo_addr == ~0ULL) goto out; + if (version_printed++ == 0) + ETH1394_PRINT_G (KERN_INFO, "%s\n", version); + /* We should really have our own alloc_hpsbdev() function in * net_init.c instead of calling the one for ethernet then hijacking * it for ourselves. That way we'd be a real networking device. */ @@ -1014,7 +1021,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len) } } - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc(sizeof(struct fragment_info), GFP_ATOMIC); if (!new) return -ENOMEM; @@ -1033,7 +1040,7 @@ static inline int new_partial_datagram(struct net_device *dev, { struct partial_datagram *new; - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc(sizeof(struct partial_datagram), GFP_ATOMIC); if (!new) return -ENOMEM; @@ -1761,6 +1768,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) static void ether1394_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { strcpy (info->driver, driver_name); + strcpy (info->version, "$Rev: 1312 $"); /* FIXME XXX provide sane businfo */ strcpy (info->bus_info, "ieee1394"); } diff --git a/trunk/drivers/ieee1394/highlevel.c b/trunk/drivers/ieee1394/highlevel.c index 734b121a0554..997e1bf6297f 100644 --- a/trunk/drivers/ieee1394/highlevel.c +++ b/trunk/drivers/ieee1394/highlevel.c @@ -101,10 +101,12 @@ void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, return NULL; } - hi = kzalloc(sizeof(*hi) + data_size, GFP_ATOMIC); + hi = kmalloc(sizeof(*hi) + data_size, GFP_ATOMIC); if (!hi) return NULL; + memset(hi, 0, sizeof(*hi) + data_size); + if (data_size) { data = hi->data = hi + 1; hi->size = data_size; @@ -324,9 +326,11 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl, return retval; } - as = kmalloc(sizeof(*as), GFP_KERNEL); - if (!as) + as = (struct hpsb_address_serve *) + kmalloc(sizeof(struct hpsb_address_serve), GFP_KERNEL); + if (as == NULL) { return retval; + } INIT_LIST_HEAD(&as->host_list); INIT_LIST_HEAD(&as->hl_list); @@ -379,9 +383,11 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, return 0; } - as = kmalloc(sizeof(*as), GFP_ATOMIC); - if (!as) - return 0; + as = (struct hpsb_address_serve *) + kmalloc(sizeof(struct hpsb_address_serve), GFP_ATOMIC); + if (as == NULL) { + return 0; + } INIT_LIST_HEAD(&as->host_list); INIT_LIST_HEAD(&as->hl_list); diff --git a/trunk/drivers/ieee1394/hosts.c b/trunk/drivers/ieee1394/hosts.c index ba09741fc826..aeeaeb670d03 100644 --- a/trunk/drivers/ieee1394/hosts.c +++ b/trunk/drivers/ieee1394/hosts.c @@ -61,12 +61,12 @@ static void delayed_reset_bus(void * __reset_info) static int dummy_transmit_packet(struct hpsb_host *h, struct hpsb_packet *p) { - return 0; + return 0; } static int dummy_devctl(struct hpsb_host *h, enum devctl_cmd c, int arg) { - return -1; + return -1; } static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg) @@ -75,9 +75,9 @@ static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command, unsigned } static struct hpsb_host_driver dummy_driver = { - .transmit_packet = dummy_transmit_packet, - .devctl = dummy_devctl, - .isoctl = dummy_isoctl + .transmit_packet = dummy_transmit_packet, + .devctl = dummy_devctl, + .isoctl = dummy_isoctl }; static int alloc_hostnum_cb(struct hpsb_host *host, void *__data) @@ -110,13 +110,13 @@ static DECLARE_MUTEX(host_num_alloc); struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, struct device *dev) { - struct hpsb_host *h; + struct hpsb_host *h; int i; int hostnum = 0; - h = kzalloc(sizeof(*h) + extra, SLAB_KERNEL); - if (!h) - return NULL; + h = kmalloc(sizeof(struct hpsb_host) + extra, SLAB_KERNEL); + if (!h) return NULL; + memset(h, 0, sizeof(struct hpsb_host) + extra); h->csr.rom = csr1212_create_csr(&csr_bus_ops, CSR_BUS_INFO_SIZE, h); if (!h->csr.rom) { @@ -125,7 +125,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, } h->hostdata = h + 1; - h->driver = drv; + h->driver = drv; skb_queue_head_init(&h->pending_packet_queue); INIT_LIST_HEAD(&h->addr_space); @@ -145,8 +145,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, 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); + h->topology_map = h->csr.topology_map + 3; + h->speed_map = (u8 *)(h->csr.speed_map + 2); down(&host_num_alloc); @@ -186,14 +186,14 @@ int hpsb_add_host(struct hpsb_host *host) void hpsb_remove_host(struct hpsb_host *host) { - host->is_shutdown = 1; + host->is_shutdown = 1; cancel_delayed_work(&host->delayed_reset); flush_scheduled_work(); - host->driver = &dummy_driver; + host->driver = &dummy_driver; - highlevel_remove_host(host); + highlevel_remove_host(host); hpsb_remove_extra_config_roms(host); diff --git a/trunk/drivers/ieee1394/hosts.h b/trunk/drivers/ieee1394/hosts.h index 07d188ca8495..ae9b02cc013f 100644 --- a/trunk/drivers/ieee1394/hosts.h +++ b/trunk/drivers/ieee1394/hosts.h @@ -17,47 +17,47 @@ struct hpsb_packet; struct hpsb_iso; struct hpsb_host { - struct list_head host_list; + struct list_head host_list; - void *hostdata; + void *hostdata; - atomic_t generation; + atomic_t generation; struct sk_buff_head pending_packet_queue; struct timer_list timeout; unsigned long timeout_interval; - unsigned char iso_listen_count[64]; + unsigned char iso_listen_count[64]; - int node_count; /* number of identified nodes on this bus */ - int selfid_count; /* total number of SelfIDs received */ + int node_count; /* number of identified nodes on this bus */ + int selfid_count; /* total number of SelfIDs received */ int nodes_active; /* number of nodes that are actually active */ - nodeid_t node_id; /* node ID of this host */ - nodeid_t irm_id; /* ID of this bus' isochronous resource manager */ - nodeid_t busmgr_id; /* ID of this bus' bus manager */ + nodeid_t node_id; /* node ID of this host */ + nodeid_t irm_id; /* ID of this bus' isochronous resource manager */ + nodeid_t busmgr_id; /* ID of this bus' bus manager */ - /* this nodes state */ - unsigned in_bus_reset:1; - unsigned is_shutdown:1; + /* this nodes state */ + unsigned in_bus_reset:1; + unsigned is_shutdown:1; unsigned resume_packet_sent:1; - /* this nodes' duties on the bus */ - unsigned is_root:1; - unsigned is_cycmst:1; - unsigned is_irm:1; - unsigned is_busmgr:1; + /* this nodes' duties on the bus */ + unsigned is_root:1; + unsigned is_cycmst:1; + unsigned is_irm:1; + unsigned is_busmgr:1; - int reset_retries; - quadlet_t *topology_map; - u8 *speed_map; - struct csr_control csr; + int reset_retries; + quadlet_t *topology_map; + u8 *speed_map; + struct csr_control csr; /* Per node tlabel pool allocation */ struct hpsb_tlabel_pool tpool[64]; - struct hpsb_host_driver *driver; + struct hpsb_host_driver *driver; struct pci_dev *pdev; @@ -77,34 +77,34 @@ struct hpsb_host { enum devctl_cmd { - /* Host is requested to reset its bus and cancel all outstanding async - * requests. If arg == 1, it shall also attempt to become root on the - * bus. Return void. */ - RESET_BUS, - - /* Arg is void, return value is the hardware cycle counter value. */ - GET_CYCLE_COUNTER, - - /* Set the hardware cycle counter to the value in arg, return void. - * FIXME - setting is probably not required. */ - SET_CYCLE_COUNTER, - - /* Configure hardware for new bus ID in arg, return void. */ - SET_BUS_ID, - - /* If arg true, start sending cycle start packets, stop if arg == 0. - * Return void. */ - ACT_CYCLE_MASTER, - - /* Cancel all outstanding async requests without resetting the bus. - * Return void. */ - CANCEL_REQUESTS, - - /* Start or stop receiving isochronous channel in arg. Return void. - * This acts as an optimization hint, hosts are not required not to - * listen on unrequested channels. */ - ISO_LISTEN_CHANNEL, - ISO_UNLISTEN_CHANNEL + /* Host is requested to reset its bus and cancel all outstanding async + * requests. If arg == 1, it shall also attempt to become root on the + * bus. Return void. */ + RESET_BUS, + + /* Arg is void, return value is the hardware cycle counter value. */ + GET_CYCLE_COUNTER, + + /* Set the hardware cycle counter to the value in arg, return void. + * FIXME - setting is probably not required. */ + SET_CYCLE_COUNTER, + + /* Configure hardware for new bus ID in arg, return void. */ + SET_BUS_ID, + + /* If arg true, start sending cycle start packets, stop if arg == 0. + * Return void. */ + ACT_CYCLE_MASTER, + + /* Cancel all outstanding async requests without resetting the bus. + * Return void. */ + CANCEL_REQUESTS, + + /* Start or stop receiving isochronous channel in arg. Return void. + * This acts as an optimization hint, hosts are not required not to + * listen on unrequested channels. */ + ISO_LISTEN_CHANNEL, + ISO_UNLISTEN_CHANNEL }; enum isoctl_cmd { @@ -135,13 +135,13 @@ enum isoctl_cmd { }; enum reset_types { - /* 166 microsecond reset -- only type of reset available on - non-1394a capable controllers */ - LONG_RESET, + /* 166 microsecond reset -- only type of reset available on + non-1394a capable controllers */ + LONG_RESET, - /* Short (arbitrated) reset -- only available on 1394a capable - controllers */ - SHORT_RESET, + /* Short (arbitrated) reset -- only available on 1394a capable + controllers */ + SHORT_RESET, /* Variants that set force_root before issueing the bus reset */ LONG_RESET_FORCE_ROOT, SHORT_RESET_FORCE_ROOT, @@ -159,22 +159,22 @@ struct hpsb_host_driver { * reads to the ConfigROM on its own. */ void (*set_hw_config_rom) (struct hpsb_host *host, quadlet_t *config_rom); - /* This function shall implement packet transmission based on - * packet->type. It shall CRC both parts of the packet (unless - * packet->type == raw) and do byte-swapping as necessary or instruct - * the hardware to do so. It can return immediately after the packet - * was queued for sending. After sending, hpsb_sent_packet() has to be - * called. Return 0 on success, negative errno on failure. - * NOTE: The function must be callable in interrupt context. - */ - int (*transmit_packet) (struct hpsb_host *host, - struct hpsb_packet *packet); - - /* This function requests miscellanous services from the driver, see - * above for command codes and expected actions. Return -1 for unknown - * command, though that should never happen. - */ - int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg); + /* This function shall implement packet transmission based on + * packet->type. It shall CRC both parts of the packet (unless + * packet->type == raw) and do byte-swapping as necessary or instruct + * the hardware to do so. It can return immediately after the packet + * was queued for sending. After sending, hpsb_sent_packet() has to be + * called. Return 0 on success, negative errno on failure. + * NOTE: The function must be callable in interrupt context. + */ + int (*transmit_packet) (struct hpsb_host *host, + struct hpsb_packet *packet); + + /* This function requests miscellanous services from the driver, see + * above for command codes and expected actions. Return -1 for unknown + * command, though that should never happen. + */ + int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg); /* ISO transmission/reception functions. Return 0 on success, -1 * (or -EXXX errno code) on failure. If the low-level driver does not @@ -182,15 +182,15 @@ struct hpsb_host_driver { */ int (*isoctl) (struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg); - /* This function is mainly to redirect local CSR reads/locks to the iso - * management registers (bus manager id, bandwidth available, channels - * available) to the hardware registers in OHCI. reg is 0,1,2,3 for bus - * mgr, bwdth avail, ch avail hi, ch avail lo respectively (the same ids - * as OHCI uses). data and compare are the new data and expected data - * respectively, return value is the old value. - */ - quadlet_t (*hw_csr_reg) (struct hpsb_host *host, int reg, - quadlet_t data, quadlet_t compare); + /* This function is mainly to redirect local CSR reads/locks to the iso + * management registers (bus manager id, bandwidth available, channels + * available) to the hardware registers in OHCI. reg is 0,1,2,3 for bus + * mgr, bwdth avail, ch avail hi, ch avail lo respectively (the same ids + * as OHCI uses). data and compare are the new data and expected data + * respectively, return value is the old value. + */ + quadlet_t (*hw_csr_reg) (struct hpsb_host *host, int reg, + quadlet_t data, quadlet_t compare); }; diff --git a/trunk/drivers/ieee1394/ieee1394-ioctl.h b/trunk/drivers/ieee1394/ieee1394-ioctl.h index 156703986348..f92b566363d5 100644 --- a/trunk/drivers/ieee1394/ieee1394-ioctl.h +++ b/trunk/drivers/ieee1394/ieee1394-ioctl.h @@ -7,6 +7,14 @@ #include #include + +/* AMDTP Gets 6 */ +#define AMDTP_IOC_CHANNEL _IOW('#', 0x00, struct amdtp_ioctl) +#define AMDTP_IOC_PLUG _IOW('#', 0x01, struct amdtp_ioctl) +#define AMDTP_IOC_PING _IOW('#', 0x02, struct amdtp_ioctl) +#define AMDTP_IOC_ZAP _IO ('#', 0x03) + + /* DV1394 Gets 10 */ /* Get the driver ready to transmit video. pass a struct dv1394_init* as diff --git a/trunk/drivers/ieee1394/ieee1394.h b/trunk/drivers/ieee1394/ieee1394.h index 936d776de00a..b634a9bb365c 100644 --- a/trunk/drivers/ieee1394/ieee1394.h +++ b/trunk/drivers/ieee1394/ieee1394.h @@ -62,7 +62,6 @@ extern const char *hpsb_speedto_str[]; -/* 1394a cable PHY packets */ #define SELFID_PWRCL_NO_POWER 0x0 #define SELFID_PWRCL_PROVIDE_15W 0x1 #define SELFID_PWRCL_PROVIDE_30W 0x2 @@ -77,24 +76,8 @@ extern const char *hpsb_speedto_str[]; #define SELFID_PORT_NCONN 0x1 #define SELFID_PORT_NONE 0x0 -#define PHYPACKET_LINKON 0x40000000 -#define PHYPACKET_PHYCONFIG_R 0x00800000 -#define PHYPACKET_PHYCONFIG_T 0x00400000 -#define EXTPHYPACKET_TYPE_PING 0x00000000 -#define EXTPHYPACKET_TYPE_REMOTEACCESS_BASE 0x00040000 -#define EXTPHYPACKET_TYPE_REMOTEACCESS_PAGED 0x00140000 -#define EXTPHYPACKET_TYPE_REMOTEREPLY_BASE 0x000C0000 -#define EXTPHYPACKET_TYPE_REMOTEREPLY_PAGED 0x001C0000 -#define EXTPHYPACKET_TYPE_REMOTECOMMAND 0x00200000 -#define EXTPHYPACKET_TYPE_REMOTECONFIRMATION 0x00280000 -#define EXTPHYPACKET_TYPE_RESUME 0x003C0000 -#define EXTPHYPACKET_TYPEMASK 0xC0FC0000 - -#define PHYPACKET_PORT_SHIFT 24 -#define PHYPACKET_GAPCOUNT_SHIFT 16 - -/* 1394a PHY register map bitmasks */ +/* 1394a PHY bitmasks */ #define PHY_00_PHYSICAL_ID 0xFC #define PHY_00_R 0x02 /* Root */ #define PHY_00_PS 0x01 /* Power Status*/ diff --git a/trunk/drivers/ieee1394/ieee1394_core.c b/trunk/drivers/ieee1394/ieee1394_core.c index 64fbbb01d52a..32a1e016c85e 100644 --- a/trunk/drivers/ieee1394/ieee1394_core.c +++ b/trunk/drivers/ieee1394/ieee1394_core.c @@ -179,34 +179,34 @@ void hpsb_free_packet(struct hpsb_packet *packet) int hpsb_reset_bus(struct hpsb_host *host, int type) { - if (!host->in_bus_reset) { - host->driver->devctl(host, RESET_BUS, type); - return 0; - } else { - return 1; - } + if (!host->in_bus_reset) { + host->driver->devctl(host, RESET_BUS, type); + return 0; + } else { + return 1; + } } int hpsb_bus_reset(struct hpsb_host *host) { - if (host->in_bus_reset) { - HPSB_NOTICE("%s called while bus reset already in progress", + if (host->in_bus_reset) { + HPSB_NOTICE("%s called while bus reset already in progress", __FUNCTION__); - return 1; - } + return 1; + } - abort_requests(host); - host->in_bus_reset = 1; - host->irm_id = -1; + abort_requests(host); + host->in_bus_reset = 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->selfid_count = 0; + host->node_count = 0; + host->selfid_count = 0; - return 0; + return 0; } @@ -216,156 +216,150 @@ int hpsb_bus_reset(struct hpsb_host *host) */ static int check_selfids(struct hpsb_host *host) { - int nodeid = -1; - int rest_of_selfids = host->selfid_count; - struct selfid *sid = (struct selfid *)host->topology_map; - struct ext_selfid *esid; - int esid_seq = 23; + int nodeid = -1; + int rest_of_selfids = host->selfid_count; + struct selfid *sid = (struct selfid *)host->topology_map; + struct ext_selfid *esid; + int esid_seq = 23; host->nodes_active = 0; - while (rest_of_selfids--) { - if (!sid->extended) { - nodeid++; - esid_seq = 0; + while (rest_of_selfids--) { + if (!sid->extended) { + nodeid++; + esid_seq = 0; - if (sid->phy_id != nodeid) { - HPSB_INFO("SelfIDs failed monotony check with " - "%d", sid->phy_id); - return 0; - } + if (sid->phy_id != nodeid) { + HPSB_INFO("SelfIDs failed monotony check with " + "%d", sid->phy_id); + return 0; + } if (sid->link_active) { host->nodes_active++; if (sid->contender) host->irm_id = LOCAL_BUS | sid->phy_id; } - } else { - esid = (struct ext_selfid *)sid; - - if ((esid->phy_id != nodeid) - || (esid->seq_nr != esid_seq)) { - HPSB_INFO("SelfIDs failed monotony check with " - "%d/%d", esid->phy_id, esid->seq_nr); - return 0; - } - esid_seq++; - } - sid++; - } - - esid = (struct ext_selfid *)(sid - 1); - while (esid->extended) { - if ((esid->porta == SELFID_PORT_PARENT) || - (esid->portb == SELFID_PORT_PARENT) || - (esid->portc == SELFID_PORT_PARENT) || - (esid->portd == SELFID_PORT_PARENT) || - (esid->porte == SELFID_PORT_PARENT) || - (esid->portf == SELFID_PORT_PARENT) || - (esid->portg == SELFID_PORT_PARENT) || - (esid->porth == SELFID_PORT_PARENT)) { + } else { + esid = (struct ext_selfid *)sid; + + if ((esid->phy_id != nodeid) + || (esid->seq_nr != esid_seq)) { + HPSB_INFO("SelfIDs failed monotony check with " + "%d/%d", esid->phy_id, esid->seq_nr); + return 0; + } + esid_seq++; + } + sid++; + } + + esid = (struct ext_selfid *)(sid - 1); + while (esid->extended) { + if ((esid->porta == 0x2) || (esid->portb == 0x2) + || (esid->portc == 0x2) || (esid->portd == 0x2) + || (esid->porte == 0x2) || (esid->portf == 0x2) + || (esid->portg == 0x2) || (esid->porth == 0x2)) { HPSB_INFO("SelfIDs failed root check on " "extended SelfID"); return 0; - } - esid--; - } + } + esid--; + } - sid = (struct selfid *)esid; - if ((sid->port0 == SELFID_PORT_PARENT) || - (sid->port1 == SELFID_PORT_PARENT) || - (sid->port2 == SELFID_PORT_PARENT)) { + sid = (struct selfid *)esid; + if ((sid->port0 == 0x2) || (sid->port1 == 0x2) || (sid->port2 == 0x2)) { HPSB_INFO("SelfIDs failed root check"); return 0; - } + } host->node_count = nodeid + 1; - return 1; + return 1; } static void build_speed_map(struct hpsb_host *host, int nodecount) { u8 speedcap[nodecount]; u8 cldcnt[nodecount]; - u8 *map = host->speed_map; - struct selfid *sid; - struct ext_selfid *esid; - int i, j, n; - - for (i = 0; i < (nodecount * 64); i += 64) { - for (j = 0; j < nodecount; j++) { - map[i+j] = IEEE1394_SPEED_MAX; - } - } - - for (i = 0; i < nodecount; i++) { - cldcnt[i] = 0; - } - - /* find direct children count and speed */ - for (sid = (struct selfid *)&host->topology_map[host->selfid_count-1], - n = nodecount - 1; - (void *)sid >= (void *)host->topology_map; sid--) { - if (sid->extended) { - esid = (struct ext_selfid *)sid; - - if (esid->porta == SELFID_PORT_CHILD) cldcnt[n]++; - if (esid->portb == SELFID_PORT_CHILD) cldcnt[n]++; - if (esid->portc == SELFID_PORT_CHILD) cldcnt[n]++; - if (esid->portd == SELFID_PORT_CHILD) cldcnt[n]++; - if (esid->porte == SELFID_PORT_CHILD) cldcnt[n]++; - if (esid->portf == SELFID_PORT_CHILD) cldcnt[n]++; - if (esid->portg == SELFID_PORT_CHILD) cldcnt[n]++; - if (esid->porth == SELFID_PORT_CHILD) cldcnt[n]++; + u8 *map = host->speed_map; + struct selfid *sid; + struct ext_selfid *esid; + int i, j, n; + + for (i = 0; i < (nodecount * 64); i += 64) { + for (j = 0; j < nodecount; j++) { + map[i+j] = IEEE1394_SPEED_MAX; + } + } + + for (i = 0; i < nodecount; i++) { + cldcnt[i] = 0; + } + + /* find direct children count and speed */ + for (sid = (struct selfid *)&host->topology_map[host->selfid_count-1], + n = nodecount - 1; + (void *)sid >= (void *)host->topology_map; sid--) { + if (sid->extended) { + esid = (struct ext_selfid *)sid; + + if (esid->porta == 0x3) cldcnt[n]++; + if (esid->portb == 0x3) cldcnt[n]++; + if (esid->portc == 0x3) cldcnt[n]++; + if (esid->portd == 0x3) cldcnt[n]++; + if (esid->porte == 0x3) cldcnt[n]++; + if (esid->portf == 0x3) cldcnt[n]++; + if (esid->portg == 0x3) cldcnt[n]++; + if (esid->porth == 0x3) cldcnt[n]++; } else { - if (sid->port0 == SELFID_PORT_CHILD) cldcnt[n]++; - if (sid->port1 == SELFID_PORT_CHILD) cldcnt[n]++; - if (sid->port2 == SELFID_PORT_CHILD) cldcnt[n]++; - - speedcap[n] = sid->speed; - n--; - } - } - - /* set self mapping */ - for (i = 0; i < nodecount; i++) { - map[64*i + i] = speedcap[i]; - } - - /* fix up direct children count to total children count; - * also fix up speedcaps for sibling and parent communication */ - for (i = 1; i < nodecount; i++) { - for (j = cldcnt[i], n = i - 1; j > 0; j--) { - cldcnt[i] += cldcnt[n]; - speedcap[n] = min(speedcap[n], speedcap[i]); - n -= cldcnt[n] + 1; - } - } - - for (n = 0; n < nodecount; n++) { - for (i = n - cldcnt[n]; i <= n; i++) { - for (j = 0; j < (n - cldcnt[n]); j++) { - map[j*64 + i] = map[i*64 + j] = - min(map[i*64 + j], speedcap[n]); - } - for (j = n + 1; j < nodecount; j++) { - map[j*64 + i] = map[i*64 + j] = - min(map[i*64 + j], speedcap[n]); - } - } - } + if (sid->port0 == 0x3) cldcnt[n]++; + if (sid->port1 == 0x3) cldcnt[n]++; + if (sid->port2 == 0x3) cldcnt[n]++; + + speedcap[n] = sid->speed; + n--; + } + } + + /* set self mapping */ + for (i = 0; i < nodecount; i++) { + map[64*i + i] = speedcap[i]; + } + + /* fix up direct children count to total children count; + * also fix up speedcaps for sibling and parent communication */ + for (i = 1; i < nodecount; i++) { + for (j = cldcnt[i], n = i - 1; j > 0; j--) { + cldcnt[i] += cldcnt[n]; + speedcap[n] = min(speedcap[n], speedcap[i]); + n -= cldcnt[n] + 1; + } + } + + for (n = 0; n < nodecount; n++) { + for (i = n - cldcnt[n]; i <= n; i++) { + for (j = 0; j < (n - cldcnt[n]); j++) { + map[j*64 + i] = map[i*64 + j] = + min(map[i*64 + j], speedcap[n]); + } + for (j = n + 1; j < nodecount; j++) { + map[j*64 + i] = map[i*64 + j] = + min(map[i*64 + j], speedcap[n]); + } + } + } } void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid) { - if (host->in_bus_reset) { - 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", + if (host->in_bus_reset) { + 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", sid, NODEID_TO_BUS(host->node_id)); - } + } } void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot) @@ -373,50 +367,50 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot) if (!host->in_bus_reset) HPSB_NOTICE("SelfID completion called outside of bus reset!"); - host->node_id = LOCAL_BUS | phyid; - host->is_root = isroot; + host->node_id = LOCAL_BUS | phyid; + host->is_root = isroot; - if (!check_selfids(host)) { - if (host->reset_retries++ < 20) { - /* selfid stage did not complete without error */ - HPSB_NOTICE("Error in SelfID stage, resetting"); + if (!check_selfids(host)) { + if (host->reset_retries++ < 20) { + /* selfid stage did not complete without error */ + HPSB_NOTICE("Error in SelfID stage, resetting"); host->in_bus_reset = 0; /* this should work from ohci1394 now... */ - hpsb_reset_bus(host, LONG_RESET); - return; - } else { - HPSB_NOTICE("Stopping out-of-control reset loop"); - HPSB_NOTICE("Warning - topology map and speed map will not be valid"); + hpsb_reset_bus(host, LONG_RESET); + return; + } 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 { + } + } else { host->reset_retries = 0; - build_speed_map(host, host->node_count); - } + build_speed_map(host, host->node_count); + } 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; - } else { - host->is_busmgr = 0; - host->is_irm = 0; - } + /* irm_id is kept up to date by check_selfids() */ + if (host->irm_id == host->node_id) { + host->is_irm = 1; + } else { + host->is_busmgr = 0; + host->is_irm = 0; + } - if (isroot) { + if (isroot) { host->driver->devctl(host, ACT_CYCLE_MASTER, 1); host->is_cycmst = 1; } atomic_inc(&host->generation); host->in_bus_reset = 0; - highlevel_host_reset(host); + highlevel_host_reset(host); } void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, - int ackcode) + int ackcode) { unsigned long flags; @@ -463,7 +457,6 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt) { struct hpsb_packet *packet; - quadlet_t d = 0; int retval = 0; if (rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 || @@ -473,16 +466,26 @@ int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt) return -EINVAL; } + packet = hpsb_alloc_packet(0); + if (!packet) + return -ENOMEM; + + packet->host = host; + packet->header_size = 8; + packet->data_size = 0; + packet->expect_response = 0; + packet->no_waiter = 0; + packet->type = hpsb_raw; + packet->header[0] = 0; if (rootid != -1) - d |= PHYPACKET_PHYCONFIG_R | rootid << PHYPACKET_PORT_SHIFT; + packet->header[0] |= rootid << 24 | 1 << 23; if (gapcnt != -1) - d |= PHYPACKET_PHYCONFIG_T | gapcnt << PHYPACKET_GAPCOUNT_SHIFT; + packet->header[0] |= gapcnt << 16 | 1 << 22; - packet = hpsb_make_phypacket(host, d); - if (!packet) - return -ENOMEM; + packet->header[1] = ~packet->header[0]; packet->generation = get_hpsb_generation(host); + retval = hpsb_send_packet_and_wait(packet); hpsb_free_packet(packet); @@ -507,13 +510,13 @@ int hpsb_send_packet(struct hpsb_packet *packet) { struct hpsb_host *host = packet->host; - if (host->is_shutdown) + if (host->is_shutdown) return -EINVAL; if (host->in_bus_reset || (packet->generation != get_hpsb_generation(host))) - return -EAGAIN; + return -EAGAIN; - packet->state = hpsb_queued; + packet->state = hpsb_queued; /* This just seems silly to me */ WARN_ON(packet->no_waiter && packet->expect_response); @@ -527,42 +530,42 @@ int hpsb_send_packet(struct hpsb_packet *packet) skb_queue_tail(&host->pending_packet_queue, packet->skb); } - if (packet->node_id == host->node_id) { + if (packet->node_id == host->node_id) { /* it is a local request, so handle it locally */ - quadlet_t *data; - size_t size = packet->data_size + packet->header_size; + quadlet_t *data; + size_t size = packet->data_size + packet->header_size; - data = kmalloc(size, GFP_ATOMIC); - if (!data) { - HPSB_ERR("unable to allocate memory for concatenating header and data"); - return -ENOMEM; - } + data = kmalloc(size, GFP_ATOMIC); + if (!data) { + HPSB_ERR("unable to allocate memory for concatenating header and data"); + return -ENOMEM; + } - memcpy(data, packet->header, packet->header_size); + memcpy(data, packet->header, packet->header_size); - if (packet->data_size) + if (packet->data_size) memcpy(((u8*)data) + packet->header_size, packet->data, packet->data_size); - dump_packet("send packet local", packet->header, packet->header_size, -1); + dump_packet("send packet local", packet->header, packet->header_size, -1); - hpsb_packet_sent(host, packet, packet->expect_response ? ACK_PENDING : ACK_COMPLETE); - hpsb_packet_received(host, data, size, 0); + hpsb_packet_sent(host, packet, packet->expect_response ? ACK_PENDING : ACK_COMPLETE); + hpsb_packet_received(host, data, size, 0); - kfree(data); + kfree(data); - return 0; - } + return 0; + } - if (packet->type == hpsb_async && packet->node_id != ALL_NODES) { - packet->speed_code = - host->speed_map[NODEID_TO_NODE(host->node_id) * 64 - + NODEID_TO_NODE(packet->node_id)]; - } + if (packet->type == hpsb_async && packet->node_id != ALL_NODES) { + packet->speed_code = + host->speed_map[NODEID_TO_NODE(host->node_id) * 64 + + NODEID_TO_NODE(packet->node_id)]; + } - dump_packet("send packet", packet->header, packet->header_size, packet->speed_code); + dump_packet("send packet", packet->header, packet->header_size, packet->speed_code); - return host->driver->transmit_packet(host, packet); + return host->driver->transmit_packet(host, packet); } /* We could just use complete() directly as the packet complete @@ -590,81 +593,81 @@ int hpsb_send_packet_and_wait(struct hpsb_packet *packet) static void send_packet_nocare(struct hpsb_packet *packet) { - if (hpsb_send_packet(packet) < 0) { - hpsb_free_packet(packet); - } + if (hpsb_send_packet(packet) < 0) { + hpsb_free_packet(packet); + } } static void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data, size_t size) { - struct hpsb_packet *packet = NULL; + struct hpsb_packet *packet = NULL; struct sk_buff *skb; - int tcode_match = 0; - int tlabel; - unsigned long flags; + int tcode_match = 0; + int tlabel; + unsigned long flags; - tlabel = (data[0] >> 10) & 0x3f; + tlabel = (data[0] >> 10) & 0x3f; spin_lock_irqsave(&host->pending_packet_queue.lock, flags); skb_queue_walk(&host->pending_packet_queue, skb) { packet = (struct hpsb_packet *)skb->data; - if ((packet->tlabel == tlabel) - && (packet->node_id == (data[1] >> 16))){ - break; - } + if ((packet->tlabel == tlabel) + && (packet->node_id == (data[1] >> 16))){ + break; + } packet = NULL; - } + } if (packet == NULL) { - HPSB_DEBUG("unsolicited response packet received - no tlabel match"); - dump_packet("contents", data, 16, -1); + HPSB_DEBUG("unsolicited response packet received - no tlabel match"); + dump_packet("contents", data, 16, -1); spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); - return; - } + return; + } - switch (packet->tcode) { - case TCODE_WRITEQ: - case TCODE_WRITEB: - if (tcode != TCODE_WRITE_RESPONSE) + switch (packet->tcode) { + case TCODE_WRITEQ: + case TCODE_WRITEB: + if (tcode != TCODE_WRITE_RESPONSE) break; tcode_match = 1; memcpy(packet->header, data, 12); - break; - case TCODE_READQ: - if (tcode != TCODE_READQ_RESPONSE) + break; + case TCODE_READQ: + if (tcode != TCODE_READQ_RESPONSE) break; tcode_match = 1; memcpy(packet->header, data, 16); - break; - case TCODE_READB: - if (tcode != TCODE_READB_RESPONSE) + break; + case TCODE_READB: + if (tcode != TCODE_READB_RESPONSE) break; tcode_match = 1; BUG_ON(packet->skb->len - sizeof(*packet) < size - 16); memcpy(packet->header, data, 16); memcpy(packet->data, data + 4, size - 16); - break; - case TCODE_LOCK_REQUEST: - if (tcode != TCODE_LOCK_RESPONSE) + break; + case TCODE_LOCK_REQUEST: + if (tcode != TCODE_LOCK_RESPONSE) break; tcode_match = 1; size = min((size - 16), (size_t)8); BUG_ON(packet->skb->len - sizeof(*packet) < size); memcpy(packet->header, data, 16); memcpy(packet->data, data + 4, size); - break; - } + break; + } - if (!tcode_match) { + if (!tcode_match) { spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); - HPSB_INFO("unsolicited response packet received - tcode mismatch"); - dump_packet("contents", data, 16, -1); - return; - } + HPSB_INFO("unsolicited response packet received - tcode mismatch"); + dump_packet("contents", data, 16, -1); + return; + } __skb_unlink(skb, &host->pending_packet_queue); @@ -683,27 +686,27 @@ static void handle_packet_response(struct hpsb_host *host, int tcode, static struct hpsb_packet *create_reply_packet(struct hpsb_host *host, quadlet_t *data, size_t dsize) { - struct hpsb_packet *p; + struct hpsb_packet *p; - p = hpsb_alloc_packet(dsize); - if (unlikely(p == NULL)) { - /* FIXME - send data_error response */ - return NULL; - } + p = hpsb_alloc_packet(dsize); + if (unlikely(p == NULL)) { + /* FIXME - send data_error response */ + return NULL; + } - p->type = hpsb_async; - p->state = hpsb_unused; - p->host = host; - p->node_id = data[1] >> 16; - p->tlabel = (data[0] >> 10) & 0x3f; - p->no_waiter = 1; + p->type = hpsb_async; + p->state = hpsb_unused; + p->host = host; + p->node_id = data[1] >> 16; + p->tlabel = (data[0] >> 10) & 0x3f; + p->no_waiter = 1; p->generation = get_hpsb_generation(host); if (dsize % 4) p->data[dsize / 4] = 0; - return p; + return p; } #define PREP_ASYNC_HEAD_RCODE(tc) \ @@ -714,7 +717,7 @@ static struct hpsb_packet *create_reply_packet(struct hpsb_host *host, packet->header[2] = 0 static void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode, - quadlet_t data) + quadlet_t data) { PREP_ASYNC_HEAD_RCODE(TCODE_READQ_RESPONSE); packet->header[3] = data; @@ -723,7 +726,7 @@ static void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode, } static void fill_async_readblock_resp(struct hpsb_packet *packet, int rcode, - int length) + int length) { if (rcode != RCODE_COMPLETE) length = 0; @@ -743,7 +746,7 @@ static void fill_async_write_resp(struct hpsb_packet *packet, int rcode) } static void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extcode, - int length) + int length) { if (rcode != RCODE_COMPLETE) length = 0; @@ -755,184 +758,184 @@ static void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extc } #define PREP_REPLY_PACKET(length) \ - packet = create_reply_packet(host, data, length); \ - if (packet == NULL) break + packet = create_reply_packet(host, data, length); \ + if (packet == NULL) break static void handle_incoming_packet(struct hpsb_host *host, int tcode, quadlet_t *data, size_t size, int write_acked) { - struct hpsb_packet *packet; - int length, rcode, extcode; - quadlet_t buffer; - nodeid_t source = data[1] >> 16; - nodeid_t dest = data[0] >> 16; - u16 flags = (u16) data[0]; - u64 addr; - - /* big FIXME - no error checking is done for an out of bounds length */ - - switch (tcode) { - case TCODE_WRITEQ: - addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; - rcode = highlevel_write(host, source, dest, data+3, + struct hpsb_packet *packet; + int length, rcode, extcode; + quadlet_t buffer; + nodeid_t source = data[1] >> 16; + nodeid_t dest = data[0] >> 16; + u16 flags = (u16) data[0]; + u64 addr; + + /* big FIXME - no error checking is done for an out of bounds length */ + + switch (tcode) { + case TCODE_WRITEQ: + addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; + rcode = highlevel_write(host, source, dest, data+3, addr, 4, flags); - if (!write_acked - && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK) - && (rcode >= 0)) { - /* not a broadcast write, reply */ - PREP_REPLY_PACKET(0); - fill_async_write_resp(packet, rcode); - send_packet_nocare(packet); - } - break; - - case TCODE_WRITEB: - addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; - rcode = highlevel_write(host, source, dest, data+4, + if (!write_acked + && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK) + && (rcode >= 0)) { + /* not a broadcast write, reply */ + PREP_REPLY_PACKET(0); + fill_async_write_resp(packet, rcode); + send_packet_nocare(packet); + } + break; + + case TCODE_WRITEB: + addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; + rcode = highlevel_write(host, source, dest, data+4, addr, data[3]>>16, flags); - if (!write_acked - && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK) - && (rcode >= 0)) { - /* not a broadcast write, reply */ - PREP_REPLY_PACKET(0); - fill_async_write_resp(packet, rcode); - send_packet_nocare(packet); - } - break; - - case TCODE_READQ: - addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; - rcode = highlevel_read(host, source, &buffer, addr, 4, flags); - - if (rcode >= 0) { - PREP_REPLY_PACKET(0); - fill_async_readquad_resp(packet, rcode, buffer); - send_packet_nocare(packet); - } - break; - - case TCODE_READB: - length = data[3] >> 16; - PREP_REPLY_PACKET(length); - - addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; - rcode = highlevel_read(host, source, packet->data, addr, - length, flags); - - if (rcode >= 0) { - fill_async_readblock_resp(packet, rcode, length); - send_packet_nocare(packet); - } else { - hpsb_free_packet(packet); - } - break; - - case TCODE_LOCK_REQUEST: - length = data[3] >> 16; - extcode = data[3] & 0xffff; - addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; - - PREP_REPLY_PACKET(8); - - if ((extcode == 0) || (extcode >= 7)) { - /* let switch default handle error */ - length = 0; - } - - switch (length) { - case 4: - rcode = highlevel_lock(host, source, packet->data, addr, - data[4], 0, extcode,flags); - fill_async_lock_resp(packet, rcode, extcode, 4); - break; - case 8: - if ((extcode != EXTCODE_FETCH_ADD) - && (extcode != EXTCODE_LITTLE_ADD)) { - rcode = highlevel_lock(host, source, - packet->data, addr, - data[5], data[4], - extcode, flags); - fill_async_lock_resp(packet, rcode, extcode, 4); - } else { - rcode = highlevel_lock64(host, source, - (octlet_t *)packet->data, addr, - *(octlet_t *)(data + 4), 0ULL, - extcode, flags); - fill_async_lock_resp(packet, rcode, extcode, 8); - } - break; - case 16: - rcode = highlevel_lock64(host, source, - (octlet_t *)packet->data, addr, - *(octlet_t *)(data + 6), - *(octlet_t *)(data + 4), - extcode, flags); - fill_async_lock_resp(packet, rcode, extcode, 8); - break; - default: - rcode = RCODE_TYPE_ERROR; - fill_async_lock_resp(packet, rcode, - extcode, 0); - } - - if (rcode >= 0) { - send_packet_nocare(packet); - } else { - hpsb_free_packet(packet); - } - break; - } + if (!write_acked + && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK) + && (rcode >= 0)) { + /* not a broadcast write, reply */ + PREP_REPLY_PACKET(0); + fill_async_write_resp(packet, rcode); + send_packet_nocare(packet); + } + break; + + case TCODE_READQ: + addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; + rcode = highlevel_read(host, source, &buffer, addr, 4, flags); + + if (rcode >= 0) { + PREP_REPLY_PACKET(0); + fill_async_readquad_resp(packet, rcode, buffer); + send_packet_nocare(packet); + } + break; + + case TCODE_READB: + length = data[3] >> 16; + PREP_REPLY_PACKET(length); + + addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; + rcode = highlevel_read(host, source, packet->data, addr, + length, flags); + + if (rcode >= 0) { + fill_async_readblock_resp(packet, rcode, length); + send_packet_nocare(packet); + } else { + hpsb_free_packet(packet); + } + break; + + case TCODE_LOCK_REQUEST: + length = data[3] >> 16; + extcode = data[3] & 0xffff; + addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; + + PREP_REPLY_PACKET(8); + + if ((extcode == 0) || (extcode >= 7)) { + /* let switch default handle error */ + length = 0; + } + + switch (length) { + case 4: + rcode = highlevel_lock(host, source, packet->data, addr, + data[4], 0, extcode,flags); + fill_async_lock_resp(packet, rcode, extcode, 4); + break; + case 8: + if ((extcode != EXTCODE_FETCH_ADD) + && (extcode != EXTCODE_LITTLE_ADD)) { + rcode = highlevel_lock(host, source, + packet->data, addr, + data[5], data[4], + extcode, flags); + fill_async_lock_resp(packet, rcode, extcode, 4); + } else { + rcode = highlevel_lock64(host, source, + (octlet_t *)packet->data, addr, + *(octlet_t *)(data + 4), 0ULL, + extcode, flags); + fill_async_lock_resp(packet, rcode, extcode, 8); + } + break; + case 16: + rcode = highlevel_lock64(host, source, + (octlet_t *)packet->data, addr, + *(octlet_t *)(data + 6), + *(octlet_t *)(data + 4), + extcode, flags); + fill_async_lock_resp(packet, rcode, extcode, 8); + break; + default: + rcode = RCODE_TYPE_ERROR; + fill_async_lock_resp(packet, rcode, + extcode, 0); + } + + if (rcode >= 0) { + send_packet_nocare(packet); + } else { + hpsb_free_packet(packet); + } + break; + } } #undef PREP_REPLY_PACKET void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, - int write_acked) + int write_acked) { - int tcode; - - if (host->in_bus_reset) { - HPSB_INFO("received packet during reset; ignoring"); - return; - } - - dump_packet("received packet", data, size, -1); - - tcode = (data[0] >> 4) & 0xf; - - switch (tcode) { - case TCODE_WRITE_RESPONSE: - case TCODE_READQ_RESPONSE: - case TCODE_READB_RESPONSE: - case TCODE_LOCK_RESPONSE: - handle_packet_response(host, tcode, data, size); - break; - - case TCODE_WRITEQ: - case TCODE_WRITEB: - case TCODE_READQ: - case TCODE_READB: - case TCODE_LOCK_REQUEST: - handle_incoming_packet(host, tcode, data, size, write_acked); - break; - - - case TCODE_ISO_DATA: - highlevel_iso_receive(host, data, size); - break; - - case TCODE_CYCLE_START: - /* simply ignore this packet if it is passed on */ - break; - - default: - HPSB_NOTICE("received packet with bogus transaction code %d", - tcode); - break; - } + int tcode; + + if (host->in_bus_reset) { + HPSB_INFO("received packet during reset; ignoring"); + return; + } + + dump_packet("received packet", data, size, -1); + + tcode = (data[0] >> 4) & 0xf; + + switch (tcode) { + case TCODE_WRITE_RESPONSE: + case TCODE_READQ_RESPONSE: + case TCODE_READB_RESPONSE: + case TCODE_LOCK_RESPONSE: + handle_packet_response(host, tcode, data, size); + break; + + case TCODE_WRITEQ: + case TCODE_WRITEB: + case TCODE_READQ: + case TCODE_READB: + case TCODE_LOCK_REQUEST: + handle_incoming_packet(host, tcode, data, size, write_acked); + break; + + + case TCODE_ISO_DATA: + highlevel_iso_receive(host, data, size); + break; + + case TCODE_CYCLE_START: + /* simply ignore this packet if it is passed on */ + break; + + default: + HPSB_NOTICE("received packet with bogus transaction code %d", + tcode); + break; + } } @@ -1126,7 +1129,7 @@ static int __init ieee1394_init(void) nodemgr implements functionality required of ieee1394a-2000 IRMs */ hpsb_disable_irm = 1; - + return 0; } diff --git a/trunk/drivers/ieee1394/ieee1394_core.h b/trunk/drivers/ieee1394/ieee1394_core.h index b35466023f00..0b31429d0a68 100644 --- a/trunk/drivers/ieee1394/ieee1394_core.h +++ b/trunk/drivers/ieee1394/ieee1394_core.h @@ -10,8 +10,8 @@ struct hpsb_packet { - /* This struct is basically read-only for hosts with the exception of - * the data buffer contents and xnext - see below. */ + /* This struct is basically read-only for hosts with the exception of + * the data buffer contents and xnext - see below. */ /* This can be used for host driver internal linking. * @@ -21,47 +21,47 @@ struct hpsb_packet { * driver_list when free'ing it. */ struct list_head driver_list; - nodeid_t node_id; + nodeid_t node_id; - /* Async and Iso types should be clear, raw means send-as-is, do not - * CRC! Byte swapping shall still be done in this case. */ - enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type; + /* Async and Iso types should be clear, raw means send-as-is, do not + * CRC! Byte swapping shall still be done in this case. */ + enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type; - /* Okay, this is core internal and a no care for hosts. - * queued = queued for sending - * pending = sent, waiting for response - * complete = processing completed, successful or not - */ - enum { - hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete - } __attribute__((packed)) state; + /* Okay, this is core internal and a no care for hosts. + * queued = queued for sending + * pending = sent, waiting for response + * complete = processing completed, successful or not + */ + enum { + hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete + } __attribute__((packed)) state; - /* These are core internal. */ - signed char tlabel; + /* These are core internal. */ + signed char tlabel; signed char ack_code; unsigned char tcode; - unsigned expect_response:1; - unsigned no_waiter:1; + unsigned expect_response:1; + unsigned no_waiter:1; - /* Speed to transmit with: 0 = 100Mbps, 1 = 200Mbps, 2 = 400Mbps */ - unsigned speed_code:2; + /* Speed to transmit with: 0 = 100Mbps, 1 = 200Mbps, 2 = 400Mbps */ + unsigned speed_code:2; - /* - * *header and *data are guaranteed to be 32-bit DMAable and may be - * overwritten to allow in-place byte swapping. Neither of these is - * CRCed (the sizes also don't include CRC), but contain space for at - * least one additional quadlet to allow in-place CRCing. The memory is - * also guaranteed to be DMA mappable. - */ - quadlet_t *header; - quadlet_t *data; - size_t header_size; - size_t data_size; + /* + * *header and *data are guaranteed to be 32-bit DMAable and may be + * overwritten to allow in-place byte swapping. Neither of these is + * CRCed (the sizes also don't include CRC), but contain space for at + * least one additional quadlet to allow in-place CRCing. The memory is + * also guaranteed to be DMA mappable. + */ + quadlet_t *header; + quadlet_t *data; + size_t header_size; + size_t data_size; - struct hpsb_host *host; - unsigned int generation; + struct hpsb_host *host; + unsigned int generation; atomic_t refcnt; @@ -73,10 +73,10 @@ struct hpsb_packet { /* XXX This is just a hack at the moment */ struct sk_buff *skb; - /* Store jiffies for implementing bus timeouts. */ - unsigned long sendtime; + /* Store jiffies for implementing bus timeouts. */ + unsigned long sendtime; - quadlet_t embedded_header[5]; + quadlet_t embedded_header[5]; }; /* Set a task for when a packet completes */ @@ -102,7 +102,7 @@ void hpsb_free_packet(struct hpsb_packet *packet); */ static inline unsigned int get_hpsb_generation(struct hpsb_host *host) { - return atomic_read(&host->generation); + return atomic_read(&host->generation); } /* @@ -157,7 +157,7 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot); * from within a transmit packet routine. */ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, - int ackcode); + int ackcode); /* * Hand over received packet to the core. The contents of data are expected to @@ -171,7 +171,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, * packet type. */ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, - int write_acked); + int write_acked); /* @@ -197,20 +197,20 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, * Block 15 (240-255) reserved for drivers under development, etc. */ -#define IEEE1394_MAJOR 171 +#define IEEE1394_MAJOR 171 -#define IEEE1394_MINOR_BLOCK_RAW1394 0 -#define IEEE1394_MINOR_BLOCK_VIDEO1394 1 -#define IEEE1394_MINOR_BLOCK_DV1394 2 -#define IEEE1394_MINOR_BLOCK_AMDTP 3 +#define IEEE1394_MINOR_BLOCK_RAW1394 0 +#define IEEE1394_MINOR_BLOCK_VIDEO1394 1 +#define IEEE1394_MINOR_BLOCK_DV1394 2 +#define IEEE1394_MINOR_BLOCK_AMDTP 3 #define IEEE1394_MINOR_BLOCK_EXPERIMENTAL 15 -#define IEEE1394_CORE_DEV MKDEV(IEEE1394_MAJOR, 0) -#define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16) -#define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16) -#define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16) -#define IEEE1394_AMDTP_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_AMDTP * 16) -#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16) +#define IEEE1394_CORE_DEV MKDEV(IEEE1394_MAJOR, 0) +#define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16) +#define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16) +#define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16) +#define IEEE1394_AMDTP_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_AMDTP * 16) +#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16) /* return the index (within a minor number block) of a file */ static inline unsigned char ieee1394_file_to_instance(struct file *file) diff --git a/trunk/drivers/ieee1394/ieee1394_transactions.c b/trunk/drivers/ieee1394/ieee1394_transactions.c index 3fe2f6c4a253..0aa876360f9b 100644 --- a/trunk/drivers/ieee1394/ieee1394_transactions.c +++ b/trunk/drivers/ieee1394/ieee1394_transactions.c @@ -22,7 +22,7 @@ #include "ieee1394_core.h" #include "highlevel.h" #include "nodemgr.h" -#include "ieee1394_transactions.h" + #define PREP_ASYNC_HEAD_ADDRESS(tc) \ packet->tcode = tc; \ @@ -31,82 +31,80 @@ packet->header[1] = (packet->host->node_id << 16) | (addr >> 32); \ packet->header[2] = addr & 0xffffffff + static void fill_async_readquad(struct hpsb_packet *packet, u64 addr) { - PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ); - packet->header_size = 12; - packet->data_size = 0; - packet->expect_response = 1; + PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ); + packet->header_size = 12; + packet->data_size = 0; + packet->expect_response = 1; } -static void fill_async_readblock(struct hpsb_packet *packet, u64 addr, - int length) +static void fill_async_readblock(struct hpsb_packet *packet, u64 addr, int length) { - PREP_ASYNC_HEAD_ADDRESS(TCODE_READB); - packet->header[3] = length << 16; - packet->header_size = 16; - packet->data_size = 0; - packet->expect_response = 1; + PREP_ASYNC_HEAD_ADDRESS(TCODE_READB); + packet->header[3] = length << 16; + packet->header_size = 16; + packet->data_size = 0; + packet->expect_response = 1; } -static void fill_async_writequad(struct hpsb_packet *packet, u64 addr, - quadlet_t data) +static void fill_async_writequad(struct hpsb_packet *packet, u64 addr, quadlet_t data) { - PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEQ); - packet->header[3] = data; - packet->header_size = 16; - packet->data_size = 0; - packet->expect_response = 1; + PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEQ); + packet->header[3] = data; + packet->header_size = 16; + packet->data_size = 0; + packet->expect_response = 1; } -static void fill_async_writeblock(struct hpsb_packet *packet, u64 addr, - int length) +static void fill_async_writeblock(struct hpsb_packet *packet, u64 addr, int length) { - PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEB); - packet->header[3] = length << 16; - packet->header_size = 16; - packet->expect_response = 1; - packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0); + PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEB); + packet->header[3] = length << 16; + packet->header_size = 16; + packet->expect_response = 1; + packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0); } static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode, - int length) + int length) { - PREP_ASYNC_HEAD_ADDRESS(TCODE_LOCK_REQUEST); - packet->header[3] = (length << 16) | extcode; - packet->header_size = 16; - packet->data_size = length; - packet->expect_response = 1; + PREP_ASYNC_HEAD_ADDRESS(TCODE_LOCK_REQUEST); + packet->header[3] = (length << 16) | extcode; + packet->header_size = 16; + packet->data_size = length; + packet->expect_response = 1; } static void fill_iso_packet(struct hpsb_packet *packet, int length, int channel, - int tag, int sync) + int tag, int sync) { - packet->header[0] = (length << 16) | (tag << 14) | (channel << 8) - | (TCODE_ISO_DATA << 4) | sync; + packet->header[0] = (length << 16) | (tag << 14) | (channel << 8) + | (TCODE_ISO_DATA << 4) | sync; - packet->header_size = 4; - packet->data_size = length; - packet->type = hpsb_iso; - packet->tcode = TCODE_ISO_DATA; + packet->header_size = 4; + packet->data_size = length; + packet->type = hpsb_iso; + packet->tcode = TCODE_ISO_DATA; } static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data) { - packet->header[0] = data; - packet->header[1] = ~data; - packet->header_size = 8; - packet->data_size = 0; - packet->expect_response = 0; - packet->type = hpsb_raw; /* No CRC added */ - packet->speed_code = IEEE1394_SPEED_100; /* Force speed to be 100Mbps */ + packet->header[0] = data; + packet->header[1] = ~data; + packet->header_size = 8; + packet->data_size = 0; + packet->expect_response = 0; + packet->type = hpsb_raw; /* No CRC added */ + packet->speed_code = IEEE1394_SPEED_100; /* Force speed to be 100Mbps */ } static void fill_async_stream_packet(struct hpsb_packet *packet, int length, int channel, int tag, int sync) { packet->header[0] = (length << 16) | (tag << 14) | (channel << 8) - | (TCODE_STREAM_DATA << 4) | sync; + | (TCODE_STREAM_DATA << 4) | sync; packet->header_size = 4; packet->data_size = length; @@ -173,96 +171,99 @@ int hpsb_get_tlabel(struct hpsb_packet *packet) */ void hpsb_free_tlabel(struct hpsb_packet *packet) { - unsigned long flags; + unsigned long flags; struct hpsb_tlabel_pool *tp; tp = &packet->host->tpool[packet->node_id & NODE_MASK]; BUG_ON(packet->tlabel > 63 || packet->tlabel < 0); - spin_lock_irqsave(&tp->lock, flags); + spin_lock_irqsave(&tp->lock, flags); BUG_ON(!test_and_clear_bit(packet->tlabel, tp->pool)); - spin_unlock_irqrestore(&tp->lock, flags); + spin_unlock_irqrestore(&tp->lock, flags); up(&tp->count); } -int hpsb_packet_success(struct hpsb_packet *packet) -{ - switch (packet->ack_code) { - case ACK_PENDING: - switch ((packet->header[1] >> 12) & 0xf) { - case RCODE_COMPLETE: - return 0; - case RCODE_CONFLICT_ERROR: - return -EAGAIN; - case RCODE_DATA_ERROR: - return -EREMOTEIO; - case RCODE_TYPE_ERROR: - return -EACCES; - case RCODE_ADDRESS_ERROR: - return -EINVAL; - default: - HPSB_ERR("received reserved rcode %d from node %d", - (packet->header[1] >> 12) & 0xf, - packet->node_id); - return -EAGAIN; - } - HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__); - - case ACK_BUSY_X: - case ACK_BUSY_A: - case ACK_BUSY_B: - return -EBUSY; - - case ACK_TYPE_ERROR: - return -EACCES; - - case ACK_COMPLETE: - if (packet->tcode == TCODE_WRITEQ - || packet->tcode == TCODE_WRITEB) { - return 0; - } else { - HPSB_ERR("impossible ack_complete from node %d " - "(tcode %d)", packet->node_id, packet->tcode); - return -EAGAIN; - } - - case ACK_DATA_ERROR: - if (packet->tcode == TCODE_WRITEB - || packet->tcode == TCODE_LOCK_REQUEST) { - return -EAGAIN; - } else { - HPSB_ERR("impossible ack_data_error from node %d " - "(tcode %d)", packet->node_id, packet->tcode); - return -EAGAIN; - } - - case ACK_ADDRESS_ERROR: - return -EINVAL; - - case ACK_TARDY: - case ACK_CONFLICT_ERROR: - case ACKX_NONE: - case ACKX_SEND_ERROR: - case ACKX_ABORTED: - case ACKX_TIMEOUT: - /* error while sending */ - return -EAGAIN; - default: - HPSB_ERR("got invalid ack %d from node %d (tcode %d)", - packet->ack_code, packet->node_id, packet->tcode); - return -EAGAIN; - } - HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__); +int hpsb_packet_success(struct hpsb_packet *packet) +{ + switch (packet->ack_code) { + case ACK_PENDING: + switch ((packet->header[1] >> 12) & 0xf) { + case RCODE_COMPLETE: + return 0; + case RCODE_CONFLICT_ERROR: + return -EAGAIN; + case RCODE_DATA_ERROR: + return -EREMOTEIO; + case RCODE_TYPE_ERROR: + return -EACCES; + case RCODE_ADDRESS_ERROR: + return -EINVAL; + default: + HPSB_ERR("received reserved rcode %d from node %d", + (packet->header[1] >> 12) & 0xf, + packet->node_id); + return -EAGAIN; + } + HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__); + + case ACK_BUSY_X: + case ACK_BUSY_A: + case ACK_BUSY_B: + return -EBUSY; + + case ACK_TYPE_ERROR: + return -EACCES; + + case ACK_COMPLETE: + if (packet->tcode == TCODE_WRITEQ + || packet->tcode == TCODE_WRITEB) { + return 0; + } else { + HPSB_ERR("impossible ack_complete from node %d " + "(tcode %d)", packet->node_id, packet->tcode); + return -EAGAIN; + } + + + case ACK_DATA_ERROR: + if (packet->tcode == TCODE_WRITEB + || packet->tcode == TCODE_LOCK_REQUEST) { + return -EAGAIN; + } else { + HPSB_ERR("impossible ack_data_error from node %d " + "(tcode %d)", packet->node_id, packet->tcode); + return -EAGAIN; + } + + case ACK_ADDRESS_ERROR: + return -EINVAL; + + case ACK_TARDY: + case ACK_CONFLICT_ERROR: + case ACKX_NONE: + case ACKX_SEND_ERROR: + case ACKX_ABORTED: + case ACKX_TIMEOUT: + /* error while sending */ + return -EAGAIN; + + default: + HPSB_ERR("got invalid ack %d from node %d (tcode %d)", + packet->ack_code, packet->node_id, packet->tcode); + return -EAGAIN; + } + + HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__); } struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node, u64 addr, size_t length) { - struct hpsb_packet *packet; + struct hpsb_packet *packet; if (length == 0) return NULL; @@ -287,9 +288,8 @@ struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node, return packet; } -struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, nodeid_t node, - u64 addr, quadlet_t * buffer, - size_t length) +struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node, + u64 addr, quadlet_t *buffer, size_t length) { struct hpsb_packet *packet; @@ -300,7 +300,7 @@ struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, nodeid_t node, if (!packet) return NULL; - if (length % 4) { /* zero padding bytes */ + if (length % 4) { /* zero padding bytes */ packet->data[length >> 2] = 0; } packet->host = host; @@ -322,9 +322,8 @@ struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, nodeid_t node, return packet; } -struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 * buffer, - int length, int channel, int tag, - int sync) +struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, int length, + int channel, int tag, int sync) { struct hpsb_packet *packet; @@ -335,7 +334,7 @@ struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 * buffer, if (!packet) return NULL; - if (length % 4) { /* zero padding bytes */ + if (length % 4) { /* zero padding bytes */ packet->data[length >> 2] = 0; } packet->host = host; @@ -353,15 +352,14 @@ struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 * buffer, } struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node, - u64 addr, int extcode, - quadlet_t * data, quadlet_t arg) + u64 addr, int extcode, quadlet_t *data, + quadlet_t arg) { struct hpsb_packet *p; u32 length; p = hpsb_alloc_packet(8); - if (!p) - return NULL; + if (!p) return NULL; p->host = host; p->node_id = node; @@ -390,16 +388,15 @@ struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node, return p; } -struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, - nodeid_t node, u64 addr, int extcode, - octlet_t * data, octlet_t arg) +struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node, + u64 addr, int extcode, octlet_t *data, + octlet_t arg) { struct hpsb_packet *p; u32 length; p = hpsb_alloc_packet(16); - if (!p) - return NULL; + if (!p) return NULL; p->host = host; p->node_id = node; @@ -432,18 +429,18 @@ struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, return p; } -struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data) +struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, + quadlet_t data) { - struct hpsb_packet *p; + struct hpsb_packet *p; - p = hpsb_alloc_packet(0); - if (!p) - return NULL; + p = hpsb_alloc_packet(0); + if (!p) return NULL; - p->host = host; - fill_phy_packet(p, data); + p->host = host; + fill_phy_packet(p, data); - return p; + return p; } struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, @@ -453,8 +450,7 @@ struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, struct hpsb_packet *p; p = hpsb_alloc_packet(length); - if (!p) - return NULL; + if (!p) return NULL; p->host = host; fill_iso_packet(p, length, channel, tag, sync); @@ -470,46 +466,47 @@ struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, */ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation, - u64 addr, quadlet_t * buffer, size_t length) + u64 addr, quadlet_t *buffer, size_t length) { - struct hpsb_packet *packet; - int retval = 0; + struct hpsb_packet *packet; + int retval = 0; - if (length == 0) - return -EINVAL; + if (length == 0) + return -EINVAL; - BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet + BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet packet = hpsb_make_readpacket(host, node, addr, length); - if (!packet) { - return -ENOMEM; - } + if (!packet) { + return -ENOMEM; + } packet->generation = generation; - retval = hpsb_send_packet_and_wait(packet); + retval = hpsb_send_packet_and_wait(packet); if (retval < 0) goto hpsb_read_fail; - retval = hpsb_packet_success(packet); + retval = hpsb_packet_success(packet); - if (retval == 0) { - if (length == 4) { - *buffer = packet->header[3]; - } else { - memcpy(buffer, packet->data, length); - } - } + if (retval == 0) { + if (length == 4) { + *buffer = packet->header[3]; + } else { + memcpy(buffer, packet->data, length); + } + } - hpsb_read_fail: - hpsb_free_tlabel(packet); - hpsb_free_packet(packet); +hpsb_read_fail: + hpsb_free_tlabel(packet); + hpsb_free_packet(packet); - return retval; + return retval; } + int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, - u64 addr, quadlet_t * buffer, size_t length) + u64 addr, quadlet_t *buffer, size_t length) { struct hpsb_packet *packet; int retval; @@ -517,61 +514,62 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, if (length == 0) return -EINVAL; - BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet + BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet - packet = hpsb_make_writepacket(host, node, addr, buffer, length); + packet = hpsb_make_writepacket (host, node, addr, buffer, length); if (!packet) return -ENOMEM; packet->generation = generation; - retval = hpsb_send_packet_and_wait(packet); + retval = hpsb_send_packet_and_wait(packet); if (retval < 0) goto hpsb_write_fail; - retval = hpsb_packet_success(packet); + retval = hpsb_packet_success(packet); - hpsb_write_fail: - hpsb_free_tlabel(packet); - hpsb_free_packet(packet); +hpsb_write_fail: + hpsb_free_tlabel(packet); + hpsb_free_packet(packet); - return retval; + return retval; } #if 0 int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, - u64 addr, int extcode, quadlet_t * data, quadlet_t arg) + u64 addr, int extcode, quadlet_t *data, quadlet_t arg) { - struct hpsb_packet *packet; - int retval = 0; + struct hpsb_packet *packet; + int retval = 0; - BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet + BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg); - if (!packet) - return -ENOMEM; + if (!packet) + return -ENOMEM; packet->generation = generation; - retval = hpsb_send_packet_and_wait(packet); + retval = hpsb_send_packet_and_wait(packet); if (retval < 0) goto hpsb_lock_fail; - retval = hpsb_packet_success(packet); + retval = hpsb_packet_success(packet); - if (retval == 0) { - *data = packet->data[0]; - } + if (retval == 0) { + *data = packet->data[0]; + } - hpsb_lock_fail: - hpsb_free_tlabel(packet); - hpsb_free_packet(packet); +hpsb_lock_fail: + hpsb_free_tlabel(packet); + hpsb_free_packet(packet); - return retval; + return retval; } + int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, - quadlet_t * buffer, size_t length, u32 specifier_id, + quadlet_t *buffer, size_t length, u32 specifier_id, unsigned int version) { struct hpsb_packet *packet; @@ -588,8 +586,7 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, return -ENOMEM; packet->data[0] = cpu_to_be32((host->node_id << 16) | specifier_id_hi); - packet->data[1] = - cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff)); + packet->data[1] = cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff)); memcpy(&(packet->data[2]), buffer, length - 8); @@ -604,4 +601,4 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, return retval; } -#endif /* 0 */ +#endif /* 0 */ diff --git a/trunk/drivers/ieee1394/iso.c b/trunk/drivers/ieee1394/iso.c index f26680ebef7c..615541b8b90f 100644 --- a/trunk/drivers/ieee1394/iso.c +++ b/trunk/drivers/ieee1394/iso.c @@ -36,22 +36,20 @@ void hpsb_iso_shutdown(struct hpsb_iso *iso) kfree(iso); } -static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host, - enum hpsb_iso_type type, +static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_iso_type type, unsigned int data_buf_size, unsigned int buf_packets, - int channel, int dma_mode, + int channel, + int dma_mode, int irq_interval, - void (*callback) (struct hpsb_iso - *)) + void (*callback)(struct hpsb_iso*)) { struct hpsb_iso *iso; int dma_direction; /* make sure driver supports the ISO API */ if (!host->driver->isoctl) { - printk(KERN_INFO - "ieee1394: host driver '%s' does not support the rawiso API\n", + printk(KERN_INFO "ieee1394: host driver '%s' does not support the rawiso API\n", host->driver->name); return NULL; } @@ -61,13 +59,12 @@ static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host, if (buf_packets < 2) buf_packets = 2; - if ((dma_mode < HPSB_ISO_DMA_DEFAULT) - || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER)) - dma_mode = HPSB_ISO_DMA_DEFAULT; + if ((dma_mode < HPSB_ISO_DMA_DEFAULT) || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER)) + dma_mode=HPSB_ISO_DMA_DEFAULT; if ((irq_interval < 0) || (irq_interval > buf_packets / 4)) - irq_interval = buf_packets / 4; - if (irq_interval == 0) /* really interrupt for each packet */ + irq_interval = buf_packets / 4; + if (irq_interval == 0) /* really interrupt for each packet*/ irq_interval = 1; if (channel < -1 || channel >= 64) @@ -79,10 +76,7 @@ static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host, /* allocate and write the struct hpsb_iso */ - iso = - kmalloc(sizeof(*iso) + - buf_packets * sizeof(struct hpsb_iso_packet_info), - GFP_KERNEL); + iso = kmalloc(sizeof(*iso) + buf_packets * sizeof(struct hpsb_iso_packet_info), GFP_KERNEL); if (!iso) return NULL; @@ -117,18 +111,17 @@ static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host, iso->prebuffer = 0; /* allocate the packet buffer */ - if (dma_region_alloc - (&iso->data_buf, iso->buf_size, host->pdev, dma_direction)) + if (dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction)) goto err; return iso; - err: +err: hpsb_iso_shutdown(iso); return NULL; } -int hpsb_iso_n_ready(struct hpsb_iso *iso) +int hpsb_iso_n_ready(struct hpsb_iso* iso) { unsigned long flags; int val; @@ -140,19 +133,18 @@ int hpsb_iso_n_ready(struct hpsb_iso *iso) return val; } -struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host, + +struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host, unsigned int data_buf_size, unsigned int buf_packets, int channel, int speed, int irq_interval, - void (*callback) (struct hpsb_iso *)) + void (*callback)(struct hpsb_iso*)) { struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT, data_buf_size, buf_packets, - channel, - HPSB_ISO_DMA_DEFAULT, - irq_interval, callback); + channel, HPSB_ISO_DMA_DEFAULT, irq_interval, callback); if (!iso) return NULL; @@ -165,23 +157,22 @@ struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host, iso->flags |= HPSB_ISO_DRIVER_INIT; return iso; - err: +err: hpsb_iso_shutdown(iso); return NULL; } -struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host, +struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host, unsigned int data_buf_size, unsigned int buf_packets, int channel, int dma_mode, int irq_interval, - void (*callback) (struct hpsb_iso *)) + void (*callback)(struct hpsb_iso*)) { struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV, data_buf_size, buf_packets, - channel, dma_mode, - irq_interval, callback); + channel, dma_mode, irq_interval, callback); if (!iso) return NULL; @@ -192,7 +183,7 @@ struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host, iso->flags |= HPSB_ISO_DRIVER_INIT; return iso; - err: +err: hpsb_iso_shutdown(iso); return NULL; } @@ -206,17 +197,16 @@ int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel) int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel) { - if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) - return -EINVAL; - return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel); + if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) + return -EINVAL; + return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel); } int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask) { if (iso->type != HPSB_ISO_RECV || iso->channel != -1) return -EINVAL; - return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, - (unsigned long)&mask); + return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask); } int hpsb_iso_recv_flush(struct hpsb_iso *iso) @@ -293,9 +283,7 @@ int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync) isoctl_args[2] = sync; - retval = - iso->host->driver->isoctl(iso, RECV_START, - (unsigned long)&isoctl_args[0]); + retval = iso->host->driver->isoctl(iso, RECV_START, (unsigned long) &isoctl_args[0]); if (retval) return retval; @@ -308,8 +296,7 @@ int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync) static int hpsb_iso_check_offset_len(struct hpsb_iso *iso, unsigned int offset, unsigned short len, - unsigned int *out_offset, - unsigned short *out_len) + unsigned int *out_offset, unsigned short *out_len) { if (offset >= iso->buf_size) return -EFAULT; @@ -329,8 +316,8 @@ static int hpsb_iso_check_offset_len(struct hpsb_iso *iso, return 0; } -int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, - u8 tag, u8 sy) + +int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag, u8 sy) { struct hpsb_iso_packet_info *info; unsigned long flags; @@ -347,8 +334,7 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, info = &iso->infos[iso->first_packet]; /* check for bogus offset/length */ - if (hpsb_iso_check_offset_len - (iso, offset, len, &info->offset, &info->len)) + if (hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len)) return -EFAULT; info->tag = tag; @@ -356,13 +342,13 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, spin_lock_irqsave(&iso->lock, flags); - rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long)info); + rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long) info); if (rv) goto out; /* increment cursors */ - iso->first_packet = (iso->first_packet + 1) % iso->buf_packets; - iso->xmit_cycle = (iso->xmit_cycle + 1) % 8000; + iso->first_packet = (iso->first_packet+1) % iso->buf_packets; + iso->xmit_cycle = (iso->xmit_cycle+1) % 8000; iso->n_ready_packets--; if (iso->prebuffer != 0) { @@ -373,7 +359,7 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, } } - out: +out: spin_unlock_irqrestore(&iso->lock, flags); return rv; } @@ -383,9 +369,7 @@ int hpsb_iso_xmit_sync(struct hpsb_iso *iso) if (iso->type != HPSB_ISO_XMIT) return -EINVAL; - return wait_event_interruptible(iso->waitq, - hpsb_iso_n_ready(iso) == - iso->buf_packets); + return wait_event_interruptible(iso->waitq, hpsb_iso_n_ready(iso) == iso->buf_packets); } void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error) @@ -412,8 +396,7 @@ void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error) } void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len, - u16 total_len, u16 cycle, u8 channel, u8 tag, - u8 sy) + u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy) { unsigned long flags; spin_lock_irqsave(&iso->lock, flags); @@ -433,7 +416,7 @@ void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len, info->tag = tag; info->sy = sy; - iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets; + iso->pkt_dma = (iso->pkt_dma+1) % iso->buf_packets; iso->n_ready_packets++; } @@ -452,21 +435,20 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets) spin_lock_irqsave(&iso->lock, flags); for (i = 0; i < n_packets; i++) { rv = iso->host->driver->isoctl(iso, RECV_RELEASE, - (unsigned long)&iso->infos[iso-> - first_packet]); + (unsigned long) &iso->infos[iso->first_packet]); if (rv) break; - iso->first_packet = (iso->first_packet + 1) % iso->buf_packets; + iso->first_packet = (iso->first_packet+1) % iso->buf_packets; iso->n_ready_packets--; /* release memory from packets discarded when queue was full */ - if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */ + if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */ if (iso->bytes_discarded != 0) { struct hpsb_iso_packet_info inf; inf.total_len = iso->bytes_discarded; iso->host->driver->isoctl(iso, RECV_RELEASE, - (unsigned long)&inf); + (unsigned long) &inf); iso->bytes_discarded = 0; } } diff --git a/trunk/drivers/ieee1394/nodemgr.c b/trunk/drivers/ieee1394/nodemgr.c index 082c7fd239f5..f2453668acf5 100644 --- a/trunk/drivers/ieee1394/nodemgr.c +++ b/trunk/drivers/ieee1394/nodemgr.c @@ -743,20 +743,21 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr unsigned int generation) { struct hpsb_host *host = hi->host; - struct node_entry *ne; + struct node_entry *ne; - ne = kzalloc(sizeof(*ne), GFP_KERNEL); - if (!ne) - return NULL; + ne = kmalloc(sizeof(struct node_entry), GFP_KERNEL); + if (!ne) return NULL; + + memset(ne, 0, sizeof(struct node_entry)); ne->tpool = &host->tpool[nodeid & NODE_MASK]; - ne->host = host; - ne->nodeid = nodeid; + ne->host = host; + ne->nodeid = nodeid; ne->generation = generation; ne->needs_probe = 1; - ne->guid = guid; + ne->guid = guid; ne->guid_vendor_id = (guid >> 40) & 0xffffff; ne->guid_vendor_oui = nodemgr_find_oui_name(ne->guid_vendor_id); ne->csr = csr; @@ -786,7 +787,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr (host->node_id == nodeid) ? "Host" : "Node", NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid); - return ne; + return ne; } @@ -871,10 +872,12 @@ static struct unit_directory *nodemgr_process_unit_directory struct csr1212_keyval *kv; u8 last_key_id = 0; - ud = kzalloc(sizeof(*ud), GFP_KERNEL); + ud = kmalloc(sizeof(struct unit_directory), GFP_KERNEL); if (!ud) goto unit_directory_error; + memset (ud, 0, sizeof(struct unit_directory)); + ud->ne = ne; ud->ignore_driver = ignore_drivers; ud->address = ud_kv->offset + CSR1212_CONFIG_ROM_SPACE_BASE; @@ -934,10 +937,10 @@ static struct unit_directory *nodemgr_process_unit_directory /* Logical Unit Number */ if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) { if (ud->flags & UNIT_DIRECTORY_HAS_LUN) { - ud_child = kmalloc(sizeof(*ud_child), GFP_KERNEL); + ud_child = kmalloc(sizeof(struct unit_directory), GFP_KERNEL); if (!ud_child) goto unit_directory_error; - memcpy(ud_child, ud, sizeof(*ud_child)); + memcpy(ud_child, ud, sizeof(struct unit_directory)); nodemgr_register_device(ne, ud_child, &ne->device); ud_child = NULL; @@ -1197,7 +1200,7 @@ static void nodemgr_node_scan_one(struct host_info *hi, struct csr1212_csr *csr; struct nodemgr_csr_info *ci; - ci = kmalloc(sizeof(*ci), GFP_KERNEL); + ci = kmalloc(sizeof(struct nodemgr_csr_info), GFP_KERNEL); if (!ci) return; @@ -1407,28 +1410,14 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) struct hpsb_host *host = hi->host; struct class *class = &nodemgr_ne_class; struct class_device *cdev; - struct node_entry *ne; /* Do some processing of the nodes we've probed. This pulls them * into the sysfs layer if needed, and can result in processing of * unit-directories, or just updating the node and it's - * unit-directories. - * - * Run updates before probes. Usually, updates are time-critical - * while probes are time-consuming. (Well, those probes need some - * improvement...) */ - + * unit-directories. */ down_read(&class->subsys.rwsem); - list_for_each_entry(cdev, &class->children, node) { - ne = container_of(cdev, struct node_entry, class_dev); - if (!ne->needs_probe) - nodemgr_probe_ne(hi, ne, generation); - } - list_for_each_entry(cdev, &class->children, node) { - ne = container_of(cdev, struct node_entry, class_dev); - if (ne->needs_probe) - nodemgr_probe_ne(hi, ne, generation); - } + list_for_each_entry(cdev, &class->children, node) + nodemgr_probe_ne(hi, container_of(cdev, struct node_entry, class_dev), generation); up_read(&class->subsys.rwsem); @@ -1459,8 +1448,7 @@ static int nodemgr_send_resume_packet(struct hpsb_host *host) int ret = 1; packet = hpsb_make_phypacket(host, - EXTPHYPACKET_TYPE_RESUME | - NODEID_TO_NODE(host->node_id) << PHYPACKET_PORT_SHIFT); + 0x003c0000 | NODEID_TO_NODE(host->node_id) << 24); if (packet) { packet->no_waiter = 1; packet->generation = get_hpsb_generation(host); diff --git a/trunk/drivers/ieee1394/nodemgr.h b/trunk/drivers/ieee1394/nodemgr.h index 0b26616e16c3..3a2f0c02fd08 100644 --- a/trunk/drivers/ieee1394/nodemgr.h +++ b/trunk/drivers/ieee1394/nodemgr.h @@ -150,6 +150,24 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne) return ne->generation == get_hpsb_generation(ne->host); } +/* + * Returns a node entry (which has its reference count incremented) or NULL if + * the GUID in question is not known. Getting a valid entry does not mean that + * the node with this GUID is currently accessible (might be powered down). + */ +struct node_entry *hpsb_guid_get_entry(u64 guid); + +/* Same as above, but use the nodeid to get an node entry. This is not + * fool-proof by itself, since the nodeid can change. */ +struct node_entry *hpsb_nodeid_get_entry(struct hpsb_host *host, nodeid_t nodeid); + +/* + * If the entry refers to a local host, this function will return the pointer + * to the hpsb_host structure. It will return NULL otherwise. Once you have + * established it is a local host, you can use that knowledge from then on (the + * GUID won't wander to an external node). */ +struct hpsb_host *hpsb_get_host_by_ne(struct node_entry *ne); + /* * This will fill in the given, pre-initialised hpsb_packet with the current * information from the node entry (host, node ID, generation number). It will diff --git a/trunk/drivers/ieee1394/ohci1394.c b/trunk/drivers/ieee1394/ohci1394.c index b6b96fa04d62..4cf9b8f3e336 100644 --- a/trunk/drivers/ieee1394/ohci1394.c +++ b/trunk/drivers/ieee1394/ohci1394.c @@ -161,6 +161,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) #define PRINT(level, fmt, args...) \ printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args) +static char version[] __devinitdata = + "$Rev: 1313 $ Ben Collins "; + /* Module Parameters */ static int phys_dma = 1; module_param(phys_dma, int, 0644); @@ -584,13 +587,12 @@ static void ohci_initialize(struct ti_ohci *ohci) sprintf (irq_buf, "%s", __irq_itoa(ohci->dev->irq)); #endif PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%s] " - "MMIO=[%lx-%lx] Max Packet=[%d] IR/IT contexts=[%d/%d]", + "MMIO=[%lx-%lx] Max Packet=[%d]", ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10), ((((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, - ohci->nb_iso_rcv_ctx, ohci->nb_iso_xmit_ctx); + ohci->max_packet_size); /* Check all of our ports to make sure that if anything is * connected, we enable that port. */ @@ -2958,23 +2960,28 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, d->ctrlClear = 0; d->cmdPtr = 0; - d->buf_cpu = kzalloc(d->num_desc * sizeof(*d->buf_cpu), GFP_ATOMIC); - d->buf_bus = kzalloc(d->num_desc * sizeof(*d->buf_bus), GFP_ATOMIC); + d->buf_cpu = kmalloc(d->num_desc * sizeof(quadlet_t*), GFP_ATOMIC); + d->buf_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_ATOMIC); if (d->buf_cpu == NULL || d->buf_bus == NULL) { PRINT(KERN_ERR, "Failed to allocate dma buffer"); free_dma_rcv_ctx(d); return -ENOMEM; } + memset(d->buf_cpu, 0, d->num_desc * sizeof(quadlet_t*)); + memset(d->buf_bus, 0, d->num_desc * sizeof(dma_addr_t)); - d->prg_cpu = kzalloc(d->num_desc * sizeof(*d->prg_cpu), GFP_ATOMIC); - d->prg_bus = kzalloc(d->num_desc * sizeof(*d->prg_bus), GFP_ATOMIC); + d->prg_cpu = kmalloc(d->num_desc * sizeof(struct dma_cmd*), + GFP_ATOMIC); + d->prg_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_ATOMIC); if (d->prg_cpu == NULL || d->prg_bus == NULL) { PRINT(KERN_ERR, "Failed to allocate dma prg"); free_dma_rcv_ctx(d); return -ENOMEM; } + memset(d->prg_cpu, 0, d->num_desc * sizeof(struct dma_cmd*)); + memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t)); d->spb = kmalloc(d->split_buf_size, GFP_ATOMIC); @@ -3086,14 +3093,17 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, d->ctrlClear = 0; d->cmdPtr = 0; - d->prg_cpu = kzalloc(d->num_desc * sizeof(*d->prg_cpu), GFP_KERNEL); - d->prg_bus = kzalloc(d->num_desc * sizeof(*d->prg_bus), GFP_KERNEL); + d->prg_cpu = kmalloc(d->num_desc * sizeof(struct at_dma_prg*), + GFP_KERNEL); + d->prg_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_KERNEL); if (d->prg_cpu == NULL || d->prg_bus == NULL) { PRINT(KERN_ERR, "Failed to allocate at dma prg"); free_dma_trm_ctx(d); return -ENOMEM; } + memset(d->prg_cpu, 0, d->num_desc * sizeof(struct at_dma_prg*)); + memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t)); len = sprintf(pool_name, "ohci1394_trm_prg"); sprintf(pool_name+len, "%d", num_allocs); @@ -3191,6 +3201,8 @@ static struct hpsb_host_driver ohci1394_driver = { .hw_csr_reg = ohci_hw_csr_reg, }; + + /*********************************** * PCI Driver Interface functions * ***********************************/ @@ -3205,10 +3217,15 @@ do { \ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { + static int version_printed = 0; + struct hpsb_host *host; struct ti_ohci *ohci; /* shortcut to currently handled device */ unsigned long ohci_base; + if (version_printed++ == 0) + PRINT_G(KERN_INFO, "%s", version); + if (pci_enable_device(dev)) FAIL(-ENXIO, "Failed to enable OHCI hardware"); pci_set_master(dev); @@ -3352,8 +3369,13 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, /* Determine the number of available IR and IT contexts. */ ohci->nb_iso_rcv_ctx = get_nb_iso_ctx(ohci, OHCI1394_IsoRecvIntMaskSet); + DBGMSG("%d iso receive contexts available", + ohci->nb_iso_rcv_ctx); + ohci->nb_iso_xmit_ctx = get_nb_iso_ctx(ohci, OHCI1394_IsoXmitIntMaskSet); + DBGMSG("%d iso transmit contexts available", + ohci->nb_iso_xmit_ctx); /* Set the usage bits for non-existent contexts so they can't * be allocated */ @@ -3584,6 +3606,8 @@ static struct pci_driver ohci1394_pci_driver = { .suspend = ohci1394_pci_suspend, }; + + /*********************************** * OHCI1394 Video Interface * ***********************************/ @@ -3690,6 +3714,7 @@ EXPORT_SYMBOL(ohci1394_init_iso_tasklet); EXPORT_SYMBOL(ohci1394_register_iso_tasklet); EXPORT_SYMBOL(ohci1394_unregister_iso_tasklet); + /*********************************** * General module initialization * ***********************************/ diff --git a/trunk/drivers/ieee1394/ohci1394.h b/trunk/drivers/ieee1394/ohci1394.h index 7df0962144e3..cc66c1cae250 100644 --- a/trunk/drivers/ieee1394/ohci1394.h +++ b/trunk/drivers/ieee1394/ohci1394.h @@ -219,8 +219,8 @@ struct ti_ohci { int self_id_errors; - /* Tasklets for iso receive and transmit, used by video1394 - * and dv1394 */ + /* Tasklets for iso receive and transmit, used by video1394, + * amdtp and dv1394 */ struct list_head iso_tasklet_list; spinlock_t iso_tasklet_list_lock; diff --git a/trunk/drivers/ieee1394/pcilynx.c b/trunk/drivers/ieee1394/pcilynx.c index e2edc41e1b6f..6b1ab875333b 100644 --- a/trunk/drivers/ieee1394/pcilynx.c +++ b/trunk/drivers/ieee1394/pcilynx.c @@ -1435,7 +1435,7 @@ static int __devinit add_card(struct pci_dev *dev, struct i2c_algo_bit_data i2c_adapter_data; error = -ENOMEM; - i2c_ad = kmalloc(sizeof(*i2c_ad), SLAB_KERNEL); + i2c_ad = kmalloc(sizeof(struct i2c_adapter), SLAB_KERNEL); if (!i2c_ad) FAIL("failed to allocate I2C adapter memory"); memcpy(i2c_ad, &bit_ops, sizeof(struct i2c_adapter)); diff --git a/trunk/drivers/ieee1394/raw1394.c b/trunk/drivers/ieee1394/raw1394.c index b05235639918..24411e666b21 100644 --- a/trunk/drivers/ieee1394/raw1394.c +++ b/trunk/drivers/ieee1394/raw1394.c @@ -102,9 +102,12 @@ static struct pending_request *__alloc_pending_request(gfp_t flags) { struct pending_request *req; - req = kzalloc(sizeof(*req), flags); - if (req) + req = (struct pending_request *)kmalloc(sizeof(struct pending_request), + flags); + if (req != NULL) { + memset(req, 0, sizeof(struct pending_request)); INIT_LIST_HEAD(&req->list); + } return req; } @@ -189,9 +192,9 @@ static void add_host(struct hpsb_host *host) struct host_info *hi; unsigned long flags; - hi = kmalloc(sizeof(*hi), GFP_KERNEL); + hi = (struct host_info *)kmalloc(sizeof(struct host_info), GFP_KERNEL); - if (hi) { + if (hi != NULL) { INIT_LIST_HEAD(&hi->list); hi->host = host; INIT_LIST_HEAD(&hi->file_info_list); @@ -312,8 +315,8 @@ static void iso_receive(struct hpsb_host *host, int channel, quadlet_t * data, break; if (!ibs) { - ibs = kmalloc(sizeof(*ibs) + length, - SLAB_ATOMIC); + ibs = kmalloc(sizeof(struct iso_block_store) + + length, SLAB_ATOMIC); if (!ibs) { kfree(req); break; @@ -373,8 +376,8 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction, break; if (!ibs) { - ibs = kmalloc(sizeof(*ibs) + length, - SLAB_ATOMIC); + ibs = kmalloc(sizeof(struct iso_block_store) + + length, SLAB_ATOMIC); if (!ibs) { kfree(req); break; @@ -499,9 +502,10 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) switch (req->req.type) { case RAW1394_REQ_LIST_CARDS: spin_lock_irqsave(&host_info_lock, flags); - khl = kmalloc(sizeof(*khl) * host_count, SLAB_ATOMIC); + khl = kmalloc(sizeof(struct raw1394_khost_list) * host_count, + SLAB_ATOMIC); - if (khl) { + if (khl != NULL) { req->req.misc = host_count; req->data = (quadlet_t *) khl; @@ -513,7 +517,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) } spin_unlock_irqrestore(&host_info_lock, flags); - if (khl) { + if (khl != NULL) { req->req.error = RAW1394_ERROR_NONE; req->req.length = min(req->req.length, (u32) (sizeof @@ -1643,13 +1647,13 @@ static int arm_register(struct file_info *fi, struct pending_request *req) return (-EINVAL); } /* addr-list-entry for fileinfo */ - addr = kmalloc(sizeof(*addr), SLAB_KERNEL); + addr = (struct arm_addr *)kmalloc(sizeof(struct arm_addr), SLAB_KERNEL); if (!addr) { req->req.length = 0; return (-ENOMEM); } /* allocation of addr_space_buffer */ - addr->addr_space_buffer = vmalloc(req->req.length); + addr->addr_space_buffer = (u8 *) vmalloc(req->req.length); if (!(addr->addr_space_buffer)) { kfree(addr); req->req.length = 0; @@ -2118,7 +2122,8 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) return -ENOMEM; } - cache->filled_head = kmalloc(sizeof(*cache->filled_head), GFP_KERNEL); + cache->filled_head = + kmalloc(sizeof(struct csr1212_cache_region), GFP_KERNEL); if (!cache->filled_head) { csr1212_release_keyval(fi->csr1212_dirs[dr]); fi->csr1212_dirs[dr] = NULL; @@ -2131,6 +2136,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) req->req.length)) { csr1212_release_keyval(fi->csr1212_dirs[dr]); fi->csr1212_dirs[dr] = NULL; + CSR1212_FREE(cache); ret = -EFAULT; } else { cache->len = req->req.length; @@ -2166,7 +2172,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) } } kfree(cache->filled_head); - CSR1212_FREE(cache); + kfree(cache); if (ret >= 0) { /* we have to free the request, because we queue no response, @@ -2482,8 +2488,8 @@ static int raw1394_iso_recv_packets(struct file_info *fi, void __user * uaddr) /* ensure user-supplied buffer is accessible and big enough */ if (!access_ok(VERIFY_WRITE, upackets.infos, - upackets.n_packets * - sizeof(struct raw1394_iso_packet_info))) + upackets.n_packets * + sizeof(struct raw1394_iso_packet_info))) return -EFAULT; /* copy the packet_infos out */ @@ -2516,8 +2522,8 @@ static int raw1394_iso_send_packets(struct file_info *fi, void __user * uaddr) /* ensure user-supplied buffer is accessible and big enough */ if (!access_ok(VERIFY_READ, upackets.infos, - upackets.n_packets * - sizeof(struct raw1394_iso_packet_info))) + upackets.n_packets * + sizeof(struct raw1394_iso_packet_info))) return -EFAULT; /* copy the infos structs in and queue the packets */ @@ -2678,10 +2684,11 @@ static int raw1394_open(struct inode *inode, struct file *file) { struct file_info *fi; - fi = kzalloc(sizeof(*fi), SLAB_KERNEL); - if (!fi) + fi = kmalloc(sizeof(struct file_info), SLAB_KERNEL); + if (fi == NULL) return -ENOMEM; + memset(fi, 0, sizeof(struct file_info)); fi->notification = (u8) RAW1394_NOTIFY_ON; /* busreset notification */ INIT_LIST_HEAD(&fi->list); @@ -2741,7 +2748,8 @@ static int raw1394_release(struct inode *inode, struct file *file) list) { entry = fi_hlp->addr_list.next; while (entry != &(fi_hlp->addr_list)) { - arm_addr = list_entry(entry, struct + arm_addr = list_entry(entry, + struct arm_addr, addr_list); if (arm_addr->start == @@ -2904,17 +2912,16 @@ static int __init init_raw1394(void) hpsb_register_highlevel(&raw1394_highlevel); - if (IS_ERR - (class_device_create - (hpsb_protocol_class, NULL, - MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL, - RAW1394_DEVICE_NAME))) { + if (IS_ERR(class_device_create(hpsb_protocol_class, NULL, MKDEV( + IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), + NULL, RAW1394_DEVICE_NAME))) { ret = -EFAULT; goto out_unreg; } - - devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), - S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME); + + devfs_mk_cdev(MKDEV( + IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), + S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME); cdev_init(&raw1394_cdev, &raw1394_fops); raw1394_cdev.owner = THIS_MODULE; @@ -2936,22 +2943,20 @@ static int __init init_raw1394(void) goto out; - out_dev: +out_dev: devfs_remove(RAW1394_DEVICE_NAME); class_device_destroy(hpsb_protocol_class, - MKDEV(IEEE1394_MAJOR, - IEEE1394_MINOR_BLOCK_RAW1394 * 16)); - out_unreg: + MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)); +out_unreg: hpsb_unregister_highlevel(&raw1394_highlevel); - out: +out: return ret; } static void __exit cleanup_raw1394(void) { class_device_destroy(hpsb_protocol_class, - MKDEV(IEEE1394_MAJOR, - IEEE1394_MINOR_BLOCK_RAW1394 * 16)); + MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)); cdev_del(&raw1394_cdev); devfs_remove(RAW1394_DEVICE_NAME); hpsb_unregister_highlevel(&raw1394_highlevel); diff --git a/trunk/drivers/ieee1394/sbp2.c b/trunk/drivers/ieee1394/sbp2.c index 18d7eda38851..f7e18ccc5c0a 100644 --- a/trunk/drivers/ieee1394/sbp2.c +++ b/trunk/drivers/ieee1394/sbp2.c @@ -80,6 +80,9 @@ #include "ieee1394_transactions.h" #include "sbp2.h" +static char version[] __devinitdata = + "$Rev: 1306 $ Ben Collins "; + /* * Module load parameter definitions */ @@ -148,15 +151,18 @@ static int force_inquiry_hack; module_param(force_inquiry_hack, int, 0444); MODULE_PARM_DESC(force_inquiry_hack, "Force SCSI inquiry hack (default = 0)"); + /* * Export information about protocols/devices supported by this driver. */ static struct ieee1394_device_id sbp2_id_table[] = { { - .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, - .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff, - .version = SBP2_SW_VERSION_ENTRY & 0xffffff}, - {} + .match_flags =IEEE1394_MATCH_SPECIFIER_ID | + IEEE1394_MATCH_VERSION, + .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff, + .version = SBP2_SW_VERSION_ENTRY & 0xffffff + }, + { } }; MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table); @@ -215,6 +221,7 @@ static u32 global_outstanding_dmas = 0; #define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args) + /* * Globals */ @@ -247,8 +254,8 @@ static struct hpsb_address_ops sbp2_ops = { #ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA static struct hpsb_address_ops sbp2_physdma_ops = { - .read = sbp2_handle_physdma_read, - .write = sbp2_handle_physdma_write, + .read = sbp2_handle_physdma_read, + .write = sbp2_handle_physdma_write, }; #endif @@ -280,6 +287,7 @@ static u32 sbp2_broken_inquiry_list[] = { * General utility functions **************************************/ + #ifndef __BIG_ENDIAN /* * Converts a buffer from be32 to cpu byte ordering. Length is in bytes. @@ -316,8 +324,7 @@ static __inline__ void sbp2util_cpu_to_be32_buffer(void *buffer, int length) /* * Debug packet dump routine. Length is in bytes. */ -static void sbp2util_packet_dump(void *buffer, int length, char *dump_name, - u32 dump_phys_addr) +static void sbp2util_packet_dump(void *buffer, int length, char *dump_name, u32 dump_phys_addr) { int i; unsigned char *dump = buffer; @@ -338,7 +345,7 @@ static void sbp2util_packet_dump(void *buffer, int length, char *dump_name, printk(" "); if ((i & 0xf) == 0) printk("\n "); - printk("%02x ", (int)dump[i]); + printk("%02x ", (int) dump[i]); } printk("\n"); @@ -357,9 +364,9 @@ static int sbp2util_down_timeout(atomic_t *done, int timeout) for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) { if (msleep_interruptible(100)) /* 100ms */ - return 1; + return(1); } - return (i > 0) ? 0 : 1; + return ((i > 0) ? 0:1); } /* Free's an allocated packet */ @@ -373,22 +380,21 @@ static void sbp2_free_packet(struct hpsb_packet *packet) * subaction and returns immediately. Can be used from interrupts. */ static int sbp2util_node_write_no_wait(struct node_entry *ne, u64 addr, - quadlet_t *buffer, size_t length) + quadlet_t *buffer, size_t length) { struct hpsb_packet *packet; packet = hpsb_make_writepacket(ne->host, ne->nodeid, addr, buffer, length); - if (!packet) - return -ENOMEM; + if (!packet) + return -ENOMEM; - hpsb_set_packet_complete_task(packet, - (void (*)(void *))sbp2_free_packet, + hpsb_set_packet_complete_task(packet, (void (*)(void*))sbp2_free_packet, packet); hpsb_node_fill_packet(ne, packet); - if (hpsb_send_packet(packet) < 0) { + if (hpsb_send_packet(packet) < 0) { sbp2_free_packet(packet); return -EIO; } @@ -411,22 +417,22 @@ static int sbp2util_create_command_orb_pool(struct scsi_id_instance_data *scsi_i spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); for (i = 0; i < orbs; i++) { - command = kzalloc(sizeof(*command), GFP_ATOMIC); + command = (struct sbp2_command_info *) + kmalloc(sizeof(struct sbp2_command_info), GFP_ATOMIC); if (!command) { - spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, - flags); - return -ENOMEM; + spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); + return(-ENOMEM); } + memset(command, '\0', sizeof(struct sbp2_command_info)); command->command_orb_dma = - pci_map_single(hi->host->pdev, &command->command_orb, - sizeof(struct sbp2_command_orb), - PCI_DMA_BIDIRECTIONAL); + pci_map_single (hi->host->pdev, &command->command_orb, + sizeof(struct sbp2_command_orb), + PCI_DMA_BIDIRECTIONAL); SBP2_DMA_ALLOC("single command orb DMA"); command->sge_dma = - pci_map_single(hi->host->pdev, - &command->scatter_gather_element, - sizeof(command->scatter_gather_element), - PCI_DMA_BIDIRECTIONAL); + pci_map_single (hi->host->pdev, &command->scatter_gather_element, + sizeof(command->scatter_gather_element), + PCI_DMA_BIDIRECTIONAL); SBP2_DMA_ALLOC("scatter_gather_element"); INIT_LIST_HEAD(&command->list); list_add_tail(&command->list, &scsi_id->sbp2_command_orb_completed); @@ -482,7 +488,7 @@ static struct sbp2_command_info *sbp2util_find_command_for_orb( list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) { if (command->command_orb_dma == orb) { spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); - return command; + return (command); } } } @@ -490,7 +496,7 @@ static struct sbp2_command_info *sbp2util_find_command_for_orb( SBP2_ORB_DEBUG("could not match command orb %x", (unsigned int)orb); - return NULL; + return(NULL); } /* @@ -507,12 +513,12 @@ static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_ list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) { if (command->Current_SCpnt == SCpnt) { spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); - return command; + return (command); } } } spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); - return NULL; + return(NULL); } /* @@ -539,7 +545,7 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb( SBP2_ERR("sbp2util_allocate_command_orb - No orbs available!"); } spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); - return command; + return (command); } /* Free our DMA's */ @@ -581,8 +587,7 @@ static void sbp2util_free_command_dma(struct sbp2_command_info *command) /* * This function moves a command to the completed orb list. */ -static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id, - struct sbp2_command_info *command) +static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id, struct sbp2_command_info *command) { unsigned long flags; @@ -601,6 +606,8 @@ static inline int sbp2util_node_is_available(struct scsi_id_instance_data *scsi_ return scsi_id && scsi_id->ne && !scsi_id->ne->in_limbo; } + + /********************************************* * IEEE-1394 core driver stack related section *********************************************/ @@ -620,14 +627,14 @@ static int sbp2_probe(struct device *dev) if (ud->flags & UNIT_DIRECTORY_HAS_LUN_DIRECTORY) return -ENODEV; - scsi_id = sbp2_alloc_device(ud); + scsi_id = sbp2_alloc_device(ud); - if (!scsi_id) - return -ENOMEM; + if (!scsi_id) + return -ENOMEM; - sbp2_parse_unit_directory(scsi_id, ud); + sbp2_parse_unit_directory(scsi_id, ud); - return sbp2_start_device(scsi_id); + return sbp2_start_device(scsi_id); } static int sbp2_remove(struct device *dev) @@ -712,11 +719,12 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud SBP2_DEBUG("sbp2_alloc_device"); - scsi_id = kzalloc(sizeof(*scsi_id), GFP_KERNEL); + scsi_id = kmalloc(sizeof(*scsi_id), GFP_KERNEL); if (!scsi_id) { SBP2_ERR("failed to create scsi_id"); goto failed_alloc; } + memset(scsi_id, 0, sizeof(*scsi_id)); scsi_id->ne = ud->ne; scsi_id->ud = ud; @@ -727,7 +735,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); INIT_LIST_HEAD(&scsi_id->scsi_list); spin_lock_init(&scsi_id->sbp2_command_orb_lock); - scsi_id->sbp2_lun = 0; + scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED; ud->device.driver_data = scsi_id; @@ -761,7 +769,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud /* Register our host with the SCSI stack. */ scsi_host = scsi_host_alloc(&scsi_driver_template, - sizeof(unsigned long)); + sizeof (unsigned long)); if (!scsi_host) { SBP2_ERR("failed to register scsi host"); goto failed_alloc; @@ -782,6 +790,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud return NULL; } + static void sbp2_host_reset(struct hpsb_host *host) { struct sbp2scsi_host_info *hi; @@ -795,6 +804,7 @@ static void sbp2_host_reset(struct hpsb_host *host) } } + /* * This function is where we first pull the node unique ids, and then * allocate memory and register a SBP-2 device. @@ -808,8 +818,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) /* Login FIFO DMA */ scsi_id->login_response = - pci_alloc_consistent(hi->host->pdev, - sizeof(struct sbp2_login_response), + pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_login_response), &scsi_id->login_response_dma); if (!scsi_id->login_response) goto alloc_fail; @@ -817,8 +826,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) /* Query logins ORB DMA */ scsi_id->query_logins_orb = - pci_alloc_consistent(hi->host->pdev, - sizeof(struct sbp2_query_logins_orb), + pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_query_logins_orb), &scsi_id->query_logins_orb_dma); if (!scsi_id->query_logins_orb) goto alloc_fail; @@ -826,8 +834,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) /* Query logins response DMA */ scsi_id->query_logins_response = - pci_alloc_consistent(hi->host->pdev, - sizeof(struct sbp2_query_logins_response), + pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_query_logins_response), &scsi_id->query_logins_response_dma); if (!scsi_id->query_logins_response) goto alloc_fail; @@ -835,8 +842,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) /* Reconnect ORB DMA */ scsi_id->reconnect_orb = - pci_alloc_consistent(hi->host->pdev, - sizeof(struct sbp2_reconnect_orb), + pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_reconnect_orb), &scsi_id->reconnect_orb_dma); if (!scsi_id->reconnect_orb) goto alloc_fail; @@ -844,8 +850,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) /* Logout ORB DMA */ scsi_id->logout_orb = - pci_alloc_consistent(hi->host->pdev, - sizeof(struct sbp2_logout_orb), + pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_logout_orb), &scsi_id->logout_orb_dma); if (!scsi_id->logout_orb) goto alloc_fail; @@ -853,11 +858,58 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) /* Login ORB DMA */ scsi_id->login_orb = - pci_alloc_consistent(hi->host->pdev, - sizeof(struct sbp2_login_orb), + pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_login_orb), &scsi_id->login_orb_dma); - if (!scsi_id->login_orb) - goto alloc_fail; + if (!scsi_id->login_orb) { +alloc_fail: + if (scsi_id->query_logins_response) { + pci_free_consistent(hi->host->pdev, + sizeof(struct sbp2_query_logins_response), + scsi_id->query_logins_response, + scsi_id->query_logins_response_dma); + SBP2_DMA_FREE("query logins response DMA"); + } + + if (scsi_id->query_logins_orb) { + pci_free_consistent(hi->host->pdev, + sizeof(struct sbp2_query_logins_orb), + scsi_id->query_logins_orb, + scsi_id->query_logins_orb_dma); + SBP2_DMA_FREE("query logins ORB DMA"); + } + + if (scsi_id->logout_orb) { + pci_free_consistent(hi->host->pdev, + sizeof(struct sbp2_logout_orb), + scsi_id->logout_orb, + scsi_id->logout_orb_dma); + SBP2_DMA_FREE("logout ORB DMA"); + } + + if (scsi_id->reconnect_orb) { + pci_free_consistent(hi->host->pdev, + sizeof(struct sbp2_reconnect_orb), + scsi_id->reconnect_orb, + scsi_id->reconnect_orb_dma); + SBP2_DMA_FREE("reconnect ORB DMA"); + } + + if (scsi_id->login_response) { + pci_free_consistent(hi->host->pdev, + sizeof(struct sbp2_login_response), + scsi_id->login_response, + scsi_id->login_response_dma); + SBP2_DMA_FREE("login FIFO DMA"); + } + + list_del(&scsi_id->scsi_list); + + kfree(scsi_id); + + SBP2_ERR ("Could not allocate memory for scsi_id"); + + return -ENOMEM; + } SBP2_DMA_ALLOC("consistent DMA region for login ORB"); SBP2_DEBUG("New SBP-2 device inserted, SCSI ID = %x", scsi_id->ud->id); @@ -883,7 +935,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) sbp2_remove_device(scsi_id); return -EINTR; } - + /* * Login to the sbp-2 device */ @@ -912,17 +964,10 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) error = scsi_add_device(scsi_id->scsi_host, 0, scsi_id->ud->id, 0); if (error) { SBP2_ERR("scsi_add_device failed"); - sbp2_logout_device(scsi_id); - sbp2_remove_device(scsi_id); return error; } return 0; - -alloc_fail: - SBP2_ERR("Could not allocate memory for scsi_id"); - sbp2_remove_device(scsi_id); - return -ENOMEM; } /* @@ -1009,43 +1054,50 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id) * This function deals with physical dma write requests (for adapters that do not support * physical dma in hardware). Mostly just here for debugging... */ -static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, - int destid, quadlet_t *data, u64 addr, - size_t length, u16 flags) +static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data, + u64 addr, size_t length, u16 flags) { - /* - * Manually put the data in the right place. - */ - memcpy(bus_to_virt((u32) addr), data, length); - sbp2util_packet_dump(data, length, "sbp2 phys dma write by device", - (u32) addr); - return RCODE_COMPLETE; + /* + * Manually put the data in the right place. + */ + memcpy(bus_to_virt((u32)addr), data, length); + sbp2util_packet_dump(data, length, "sbp2 phys dma write by device", (u32)addr); + return(RCODE_COMPLETE); } /* * This function deals with physical dma read requests (for adapters that do not support * physical dma in hardware). Mostly just here for debugging... */ -static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, - quadlet_t *data, u64 addr, size_t length, - u16 flags) +static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data, + u64 addr, size_t length, u16 flags) { - /* - * Grab data from memory and send a read response. - */ - memcpy(data, bus_to_virt((u32) addr), length); - sbp2util_packet_dump(data, length, "sbp2 phys dma read by device", - (u32) addr); - return RCODE_COMPLETE; + /* + * Grab data from memory and send a read response. + */ + memcpy(data, bus_to_virt((u32)addr), length); + sbp2util_packet_dump(data, length, "sbp2 phys dma read by device", (u32)addr); + return(RCODE_COMPLETE); } #endif + /************************************** * SBP-2 protocol related section **************************************/ +/* + * This function determines if we should convert scsi commands for a particular sbp2 device type + */ +static __inline__ int sbp2_command_conversion_device_type(u8 device_type) +{ + return (((device_type == TYPE_DISK) || + (device_type == TYPE_RBC) || + (device_type == TYPE_ROM)) ? 1:0); +} + /* * This function queries the device for the maximum concurrent logins it * supports. @@ -1068,7 +1120,11 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) scsi_id->query_logins_orb->lun_misc = ORB_SET_FUNCTION(SBP2_QUERY_LOGINS_REQUEST); scsi_id->query_logins_orb->lun_misc |= ORB_SET_NOTIFY(1); - scsi_id->query_logins_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_lun); + if (scsi_id->sbp2_device_type_and_lun != SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) { + scsi_id->query_logins_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun); + SBP2_DEBUG("sbp2_query_logins: set lun to %d", + ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun)); + } SBP2_DEBUG("sbp2_query_logins: lun_misc initialized"); scsi_id->query_logins_orb->reserved_resp_length = @@ -1105,12 +1161,12 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 2*HZ)) { SBP2_INFO("Error querying logins to SBP-2 device - timed out"); - return -EIO; + return(-EIO); } if (scsi_id->status_block.ORB_offset_lo != scsi_id->query_logins_orb_dma) { SBP2_INFO("Error querying logins to SBP-2 device - timed out"); - return -EIO; + return(-EIO); } if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) || @@ -1118,7 +1174,7 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) { SBP2_INFO("Error querying logins to SBP-2 device - timed out"); - return -EIO; + return(-EIO); } sbp2util_cpu_to_be32_buffer(scsi_id->query_logins_response, sizeof(struct sbp2_query_logins_response)); @@ -1135,7 +1191,7 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) SBP2_DEBUG("Number of active logins: %d", active_logins); if (active_logins >= max_logins) { - return -EIO; + return(-EIO); } return 0; @@ -1154,13 +1210,13 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) if (!scsi_id->login_orb) { SBP2_DEBUG("sbp2_login_device: login_orb not alloc'd!"); - return -EIO; + return(-EIO); } if (!exclusive_login) { if (sbp2_query_logins(scsi_id)) { SBP2_INFO("Device does not support any more concurrent logins"); - return -EIO; + return(-EIO); } } @@ -1177,7 +1233,12 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) scsi_id->login_orb->lun_misc |= ORB_SET_RECONNECT(0); /* One second reconnect time */ scsi_id->login_orb->lun_misc |= ORB_SET_EXCLUSIVE(exclusive_login); /* Exclusive access to device */ scsi_id->login_orb->lun_misc |= ORB_SET_NOTIFY(1); /* Notify us of login complete */ - scsi_id->login_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_lun); + /* Set the lun if we were able to pull it from the device's unit directory */ + if (scsi_id->sbp2_device_type_and_lun != SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) { + scsi_id->login_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun); + SBP2_DEBUG("sbp2_query_logins: set lun to %d", + ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun)); + } SBP2_DEBUG("sbp2_login_device: lun_misc initialized"); scsi_id->login_orb->passwd_resp_lengths = @@ -1227,7 +1288,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) */ if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 20*HZ)) { SBP2_ERR("Error logging into SBP-2 device - login timed-out"); - return -EIO; + return(-EIO); } /* @@ -1235,7 +1296,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) */ if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) { SBP2_ERR("Error logging into SBP-2 device - login timed-out"); - return -EIO; + return(-EIO); } /* @@ -1246,7 +1307,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) { SBP2_ERR("Error logging into SBP-2 device - login failed"); - return -EIO; + return(-EIO); } /* @@ -1270,7 +1331,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) SBP2_INFO("Logged into SBP-2 device"); - return 0; + return(0); } @@ -1324,7 +1385,8 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id) atomic_set(&scsi_id->sbp2_login_complete, 0); error = hpsb_node_write(scsi_id->ne, - scsi_id->sbp2_management_agent_addr, data, 8); + scsi_id->sbp2_management_agent_addr, + data, 8); if (error) return error; @@ -1334,7 +1396,7 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id) SBP2_INFO("Logged out of SBP-2 device"); - return 0; + return(0); } @@ -1394,7 +1456,8 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) atomic_set(&scsi_id->sbp2_login_complete, 0); error = hpsb_node_write(scsi_id->ne, - scsi_id->sbp2_management_agent_addr, data, 8); + scsi_id->sbp2_management_agent_addr, + data, 8); if (error) return error; @@ -1403,7 +1466,7 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) */ if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ)) { SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out"); - return -EIO; + return(-EIO); } /* @@ -1411,7 +1474,7 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) */ if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) { SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out"); - return -EIO; + return(-EIO); } /* @@ -1422,12 +1485,12 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) { SBP2_ERR("Error reconnecting to SBP-2 device - reconnect failed"); - return -EIO; + return(-EIO); } HPSB_DEBUG("Reconnected to SBP-2 device"); - return 0; + return(0); } @@ -1450,9 +1513,10 @@ static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id) SBP2_ERR("sbp2_set_busy_timeout error"); } - return 0; + return(0); } + /* * This function is called to parse sbp2 device's config rom unit * directory. Used to determine things like sbp2 management agent offset, @@ -1465,7 +1529,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, struct csr1212_dentry *dentry; u64 management_agent_addr; u32 command_set_spec_id, command_set, unit_characteristics, - firmware_revision, workarounds; + firmware_revision, workarounds; int i; SBP2_DEBUG("sbp2_parse_unit_directory"); @@ -1483,14 +1547,13 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, if (kv->key.type == CSR1212_KV_TYPE_CSR_OFFSET) { /* Save off the management agent address */ management_agent_addr = - CSR1212_REGISTER_SPACE_BASE + - (kv->value.csr_offset << 2); + CSR1212_REGISTER_SPACE_BASE + + (kv->value.csr_offset << 2); SBP2_DEBUG("sbp2_management_agent_addr = %x", - (unsigned int)management_agent_addr); + (unsigned int) management_agent_addr); } else if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) { - scsi_id->sbp2_lun = - ORB_SET_LUN(kv->value.immediate); + scsi_id->sbp2_device_type_and_lun = kv->value.immediate; } break; @@ -1498,14 +1561,14 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, /* Command spec organization */ command_set_spec_id = kv->value.immediate; SBP2_DEBUG("sbp2_command_set_spec_id = %x", - (unsigned int)command_set_spec_id); + (unsigned int) command_set_spec_id); break; case SBP2_COMMAND_SET_KEY: /* Command set used by sbp2 device */ command_set = kv->value.immediate; SBP2_DEBUG("sbp2_command_set = %x", - (unsigned int)command_set); + (unsigned int) command_set); break; case SBP2_UNIT_CHARACTERISTICS_KEY: @@ -1515,7 +1578,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, */ unit_characteristics = kv->value.immediate; SBP2_DEBUG("sbp2_unit_characteristics = %x", - (unsigned int)unit_characteristics); + (unsigned int) unit_characteristics); break; case SBP2_FIRMWARE_REVISION_KEY: @@ -1523,10 +1586,9 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, firmware_revision = kv->value.immediate; if (force_inquiry_hack) SBP2_INFO("sbp2_firmware_revision = %x", - (unsigned int)firmware_revision); - else - SBP2_DEBUG("sbp2_firmware_revision = %x", - (unsigned int)firmware_revision); + (unsigned int) firmware_revision); + else SBP2_DEBUG("sbp2_firmware_revision = %x", + (unsigned int) firmware_revision); break; default: @@ -1584,7 +1646,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, scsi_id->sbp2_firmware_revision = firmware_revision; scsi_id->workarounds = workarounds; if (ud->flags & UNIT_DIRECTORY_HAS_LUN) - scsi_id->sbp2_lun = ORB_SET_LUN(ud->lun); + scsi_id->sbp2_device_type_and_lun = ud->lun; } } @@ -1604,9 +1666,8 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id) SBP2_DEBUG("sbp2_max_speed_and_size"); /* Initial setting comes from the hosts speed map */ - scsi_id->speed_code = - hi->host->speed_map[NODEID_TO_NODE(hi->host->node_id) * 64 + - NODEID_TO_NODE(scsi_id->ne->nodeid)]; + scsi_id->speed_code = hi->host->speed_map[NODEID_TO_NODE(hi->host->node_id) * 64 + + NODEID_TO_NODE(scsi_id->ne->nodeid)]; /* Bump down our speed if the user requested it */ if (scsi_id->speed_code > max_speed) { @@ -1617,16 +1678,15 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id) /* Payload size is the lesser of what our speed supports and what * our host supports. */ - scsi_id->max_payload_size = - min(sbp2_speedto_max_payload[scsi_id->speed_code], - (u8) (hi->host->csr.max_rec - 1)); + scsi_id->max_payload_size = min(sbp2_speedto_max_payload[scsi_id->speed_code], + (u8)(hi->host->csr.max_rec - 1)); HPSB_DEBUG("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)); + 1 << ((u32)scsi_id->max_payload_size + 2)); - return 0; + return(0); } /* @@ -1661,187 +1721,30 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait) */ scsi_id->last_orb = NULL; - return 0; -} - -static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, - struct sbp2scsi_host_info *hi, - struct sbp2_command_info *command, - unsigned int scsi_use_sg, - struct scatterlist *sgpnt, - u32 orb_direction, - enum dma_data_direction dma_dir) -{ - command->dma_dir = dma_dir; - orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); - orb->misc |= ORB_SET_DIRECTION(orb_direction); - - /* Special case if only one element (and less than 64KB in size) */ - if ((scsi_use_sg == 1) && - (sgpnt[0].length <= SBP2_MAX_SG_ELEMENT_LENGTH)) { - - SBP2_DEBUG("Only one s/g element"); - command->dma_size = sgpnt[0].length; - command->dma_type = CMD_DMA_PAGE; - command->cmd_dma = pci_map_page(hi->host->pdev, - sgpnt[0].page, - sgpnt[0].offset, - command->dma_size, - command->dma_dir); - SBP2_DMA_ALLOC("single page scatter element"); - - orb->data_descriptor_lo = command->cmd_dma; - orb->misc |= ORB_SET_DATA_SIZE(command->dma_size); - - } else { - struct sbp2_unrestricted_page_table *sg_element = - &command->scatter_gather_element[0]; - u32 sg_count, sg_len; - dma_addr_t sg_addr; - int i, count = pci_map_sg(hi->host->pdev, sgpnt, scsi_use_sg, - dma_dir); - - SBP2_DMA_ALLOC("scatter list"); - - command->dma_size = scsi_use_sg; - command->sge_buffer = sgpnt; - - /* use page tables (s/g) */ - orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1); - orb->data_descriptor_lo = command->sge_dma; - - /* - * Loop through and fill out our sbp-2 page tables - * (and split up anything too large) - */ - for (i = 0, sg_count = 0 ; i < count; i++, sgpnt++) { - sg_len = sg_dma_len(sgpnt); - sg_addr = sg_dma_address(sgpnt); - while (sg_len) { - sg_element[sg_count].segment_base_lo = sg_addr; - if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) { - sg_element[sg_count].length_segment_base_hi = - PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH); - sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH; - sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH; - } else { - sg_element[sg_count].length_segment_base_hi = - PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len); - sg_len = 0; - } - sg_count++; - } - } - - /* Number of page table (s/g) elements */ - orb->misc |= ORB_SET_DATA_SIZE(sg_count); - - sbp2util_packet_dump(sg_element, - (sizeof(struct sbp2_unrestricted_page_table)) * sg_count, - "sbp2 s/g list", command->sge_dma); - - /* Byte swap page tables if necessary */ - sbp2util_cpu_to_be32_buffer(sg_element, - (sizeof(struct sbp2_unrestricted_page_table)) * - sg_count); - } -} - -static void sbp2_prep_command_orb_no_sg(struct sbp2_command_orb *orb, - struct sbp2scsi_host_info *hi, - struct sbp2_command_info *command, - struct scatterlist *sgpnt, - u32 orb_direction, - unsigned int scsi_request_bufflen, - void *scsi_request_buffer, - enum dma_data_direction dma_dir) -{ - command->dma_dir = dma_dir; - command->dma_size = scsi_request_bufflen; - command->dma_type = CMD_DMA_SINGLE; - command->cmd_dma = pci_map_single(hi->host->pdev, scsi_request_buffer, - command->dma_size, command->dma_dir); - orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); - orb->misc |= ORB_SET_DIRECTION(orb_direction); - - SBP2_DMA_ALLOC("single bulk"); - - /* - * Handle case where we get a command w/o s/g enabled (but - * check for transfers larger than 64K) - */ - if (scsi_request_bufflen <= SBP2_MAX_SG_ELEMENT_LENGTH) { - - orb->data_descriptor_lo = command->cmd_dma; - orb->misc |= ORB_SET_DATA_SIZE(scsi_request_bufflen); - - } else { - struct sbp2_unrestricted_page_table *sg_element = - &command->scatter_gather_element[0]; - u32 sg_count, sg_len; - dma_addr_t sg_addr; - - /* - * Need to turn this into page tables, since the - * buffer is too large. - */ - orb->data_descriptor_lo = command->sge_dma; - - /* Use page tables (s/g) */ - orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1); - - /* - * fill out our sbp-2 page tables (and split up - * the large buffer) - */ - sg_count = 0; - sg_len = scsi_request_bufflen; - sg_addr = command->cmd_dma; - while (sg_len) { - sg_element[sg_count].segment_base_lo = sg_addr; - if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) { - sg_element[sg_count].length_segment_base_hi = - PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH); - sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH; - sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH; - } else { - sg_element[sg_count].length_segment_base_hi = - PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len); - sg_len = 0; - } - sg_count++; - } - - /* Number of page table (s/g) elements */ - orb->misc |= ORB_SET_DATA_SIZE(sg_count); - - sbp2util_packet_dump(sg_element, - (sizeof(struct sbp2_unrestricted_page_table)) * sg_count, - "sbp2 s/g list", command->sge_dma); - - /* Byte swap page tables if necessary */ - sbp2util_cpu_to_be32_buffer(sg_element, - (sizeof(struct sbp2_unrestricted_page_table)) * - sg_count); - } + return(0); } /* * This function is called to create the actual command orb and s/g list * out of the scsi command itself. */ -static void sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id, - struct sbp2_command_info *command, - unchar *scsi_cmd, - unsigned int scsi_use_sg, - unsigned int scsi_request_bufflen, - void *scsi_request_buffer, - enum dma_data_direction dma_dir) +static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id, + struct sbp2_command_info *command, + unchar *scsi_cmd, + unsigned int scsi_use_sg, + unsigned int scsi_request_bufflen, + void *scsi_request_buffer, + enum dma_data_direction dma_dir) + { struct sbp2scsi_host_info *hi = scsi_id->hi; - struct scatterlist *sgpnt = (struct scatterlist *)scsi_request_buffer; + struct scatterlist *sgpnt = (struct scatterlist *) scsi_request_buffer; struct sbp2_command_orb *command_orb = &command->command_orb; - u32 orb_direction; + struct sbp2_unrestricted_page_table *scatter_gather_element = + &command->scatter_gather_element[0]; + u32 sg_count, sg_len, orb_direction; + dma_addr_t sg_addr; + int i; /* * Set-up our command ORB.. @@ -1855,42 +1758,222 @@ static void sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id, command_orb->next_ORB_lo = 0x0; command_orb->misc = ORB_SET_MAX_PAYLOAD(scsi_id->max_payload_size); command_orb->misc |= ORB_SET_SPEED(scsi_id->speed_code); - command_orb->misc |= ORB_SET_NOTIFY(1); /* Notify us when complete */ + command_orb->misc |= ORB_SET_NOTIFY(1); /* Notify us when complete */ - if (dma_dir == DMA_NONE) - orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER; - else if (dma_dir == DMA_TO_DEVICE && scsi_request_bufflen) - orb_direction = ORB_DIRECTION_WRITE_TO_MEDIA; - else if (dma_dir == DMA_FROM_DEVICE && scsi_request_bufflen) - orb_direction = ORB_DIRECTION_READ_FROM_MEDIA; - else { - SBP2_WARN("Falling back to DMA_NONE"); - orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER; + /* + * Get the direction of the transfer. If the direction is unknown, then use our + * goofy table as a back-up. + */ + switch (dma_dir) { + case DMA_NONE: + orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER; + break; + case DMA_TO_DEVICE: + orb_direction = ORB_DIRECTION_WRITE_TO_MEDIA; + break; + case DMA_FROM_DEVICE: + orb_direction = ORB_DIRECTION_READ_FROM_MEDIA; + break; + case DMA_BIDIRECTIONAL: + default: + SBP2_ERR("SCSI data transfer direction not specified. " + "Update the SBP2 direction table in sbp2.h if " + "necessary for your application"); + __scsi_print_command(scsi_cmd); + orb_direction = sbp2scsi_direction_table[*scsi_cmd]; + break; } - /* Set-up our pagetable stuff */ + /* + * Set-up our pagetable stuff... unfortunately, this has become + * messier than I'd like. Need to clean this up a bit. ;-) + */ if (orb_direction == ORB_DIRECTION_NO_DATA_TRANSFER) { + SBP2_DEBUG("No data transfer"); + + /* + * Handle no data transfer + */ command_orb->data_descriptor_hi = 0x0; command_orb->data_descriptor_lo = 0x0; command_orb->misc |= ORB_SET_DIRECTION(1); + } else if (scsi_use_sg) { + SBP2_DEBUG("Use scatter/gather"); - sbp2_prep_command_orb_sg(command_orb, hi, command, scsi_use_sg, - sgpnt, orb_direction, dma_dir); + + /* + * Special case if only one element (and less than 64KB in size) + */ + if ((scsi_use_sg == 1) && (sgpnt[0].length <= SBP2_MAX_SG_ELEMENT_LENGTH)) { + + SBP2_DEBUG("Only one s/g element"); + command->dma_dir = dma_dir; + command->dma_size = sgpnt[0].length; + command->dma_type = CMD_DMA_PAGE; + command->cmd_dma = pci_map_page(hi->host->pdev, + sgpnt[0].page, + sgpnt[0].offset, + command->dma_size, + command->dma_dir); + SBP2_DMA_ALLOC("single page scatter element"); + + command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); + command_orb->data_descriptor_lo = command->cmd_dma; + command_orb->misc |= ORB_SET_DATA_SIZE(command->dma_size); + command_orb->misc |= ORB_SET_DIRECTION(orb_direction); + + } else { + int count = pci_map_sg(hi->host->pdev, sgpnt, scsi_use_sg, dma_dir); + SBP2_DMA_ALLOC("scatter list"); + + command->dma_size = scsi_use_sg; + command->dma_dir = dma_dir; + command->sge_buffer = sgpnt; + + /* use page tables (s/g) */ + command_orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1); + command_orb->misc |= ORB_SET_DIRECTION(orb_direction); + command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); + command_orb->data_descriptor_lo = command->sge_dma; + + /* + * Loop through and fill out our sbp-2 page tables + * (and split up anything too large) + */ + for (i = 0, sg_count = 0 ; i < count; i++, sgpnt++) { + sg_len = sg_dma_len(sgpnt); + sg_addr = sg_dma_address(sgpnt); + while (sg_len) { + scatter_gather_element[sg_count].segment_base_lo = sg_addr; + if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) { + scatter_gather_element[sg_count].length_segment_base_hi = + PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH); + sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH; + sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH; + } else { + scatter_gather_element[sg_count].length_segment_base_hi = + PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len); + sg_len = 0; + } + sg_count++; + } + } + + /* Number of page table (s/g) elements */ + command_orb->misc |= ORB_SET_DATA_SIZE(sg_count); + + sbp2util_packet_dump(scatter_gather_element, + (sizeof(struct sbp2_unrestricted_page_table)) * sg_count, + "sbp2 s/g list", command->sge_dma); + + /* + * Byte swap page tables if necessary + */ + sbp2util_cpu_to_be32_buffer(scatter_gather_element, + (sizeof(struct sbp2_unrestricted_page_table)) * + sg_count); + + } + } else { + SBP2_DEBUG("No scatter/gather"); - sbp2_prep_command_orb_no_sg(command_orb, hi, command, sgpnt, - orb_direction, scsi_request_bufflen, - scsi_request_buffer, dma_dir); + + command->dma_dir = dma_dir; + command->dma_size = scsi_request_bufflen; + command->dma_type = CMD_DMA_SINGLE; + command->cmd_dma = pci_map_single (hi->host->pdev, scsi_request_buffer, + command->dma_size, + command->dma_dir); + SBP2_DMA_ALLOC("single bulk"); + + /* + * Handle case where we get a command w/o s/g enabled (but + * check for transfers larger than 64K) + */ + if (scsi_request_bufflen <= SBP2_MAX_SG_ELEMENT_LENGTH) { + + command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); + command_orb->data_descriptor_lo = command->cmd_dma; + command_orb->misc |= ORB_SET_DATA_SIZE(scsi_request_bufflen); + command_orb->misc |= ORB_SET_DIRECTION(orb_direction); + + /* + * Sanity, in case our direction table is not + * up-to-date + */ + if (!scsi_request_bufflen) { + command_orb->data_descriptor_hi = 0x0; + command_orb->data_descriptor_lo = 0x0; + command_orb->misc |= ORB_SET_DIRECTION(1); + } + + } else { + /* + * Need to turn this into page tables, since the + * buffer is too large. + */ + command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); + command_orb->data_descriptor_lo = command->sge_dma; + + /* Use page tables (s/g) */ + command_orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1); + command_orb->misc |= ORB_SET_DIRECTION(orb_direction); + + /* + * fill out our sbp-2 page tables (and split up + * the large buffer) + */ + sg_count = 0; + sg_len = scsi_request_bufflen; + sg_addr = command->cmd_dma; + while (sg_len) { + scatter_gather_element[sg_count].segment_base_lo = sg_addr; + if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) { + scatter_gather_element[sg_count].length_segment_base_hi = + PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH); + sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH; + sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH; + } else { + scatter_gather_element[sg_count].length_segment_base_hi = + PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len); + sg_len = 0; + } + sg_count++; + } + + /* Number of page table (s/g) elements */ + command_orb->misc |= ORB_SET_DATA_SIZE(sg_count); + + sbp2util_packet_dump(scatter_gather_element, + (sizeof(struct sbp2_unrestricted_page_table)) * sg_count, + "sbp2 s/g list", command->sge_dma); + + /* + * Byte swap page tables if necessary + */ + sbp2util_cpu_to_be32_buffer(scatter_gather_element, + (sizeof(struct sbp2_unrestricted_page_table)) * + sg_count); + + } + } - /* Byte swap command ORB if necessary */ + /* + * Byte swap command ORB if necessary + */ sbp2util_cpu_to_be32_buffer(command_orb, sizeof(struct sbp2_command_orb)); - /* Put our scsi command in the command ORB */ + /* + * Put our scsi command in the command ORB + */ memset(command_orb->cdb, 0, 12); memcpy(command_orb->cdb, scsi_cmd, COMMAND_SIZE(*scsi_cmd)); + + return(0); } /* @@ -1906,7 +1989,7 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, outstanding_orb_incr; SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x", - command_orb, global_outstanding_command_orbs); + command_orb, global_outstanding_command_orbs); pci_dma_sync_single_for_device(hi->host->pdev, command->command_orb_dma, sizeof(struct sbp2_command_orb), @@ -1951,11 +2034,10 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, * both by the sbp2 device and us. */ scsi_id->last_orb->next_ORB_lo = - cpu_to_be32(command->command_orb_dma); + cpu_to_be32(command->command_orb_dma); /* Tells hardware that this pointer is valid */ scsi_id->last_orb->next_ORB_hi = 0x0; - pci_dma_sync_single_for_device(hi->host->pdev, - scsi_id->last_orb_dma, + pci_dma_sync_single_for_device(hi->host->pdev, scsi_id->last_orb_dma, sizeof(struct sbp2_command_orb), PCI_DMA_BIDIRECTIONAL); @@ -1969,14 +2051,14 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, if (sbp2util_node_write_no_wait(ne, addr, &data, 4) < 0) { SBP2_ERR("sbp2util_node_write_no_wait failed"); - return -EIO; + return(-EIO); } scsi_id->last_orb = command_orb; scsi_id->last_orb_dma = command->command_orb_dma; } - return 0; + return(0); } /* @@ -2003,7 +2085,7 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, */ command = sbp2util_allocate_command_orb(scsi_id, SCpnt, done); if (!command) { - return -EIO; + return(-EIO); } /* @@ -2024,6 +2106,11 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, sbp2_create_command_orb(scsi_id, command, cmd, SCpnt->use_sg, request_bufflen, SCpnt->request_buffer, SCpnt->sc_data_direction); + /* + * Update our cdb if necessary (to handle sbp2 RBC command set + * differences). This is where the command set hacks go! =) + */ + sbp2_check_sbp2_command(scsi_id, command->command_orb.cdb); sbp2util_packet_dump(&command->command_orb, sizeof(struct sbp2_command_orb), "sbp2 command orb", command->command_orb_dma); @@ -2038,7 +2125,112 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, */ sbp2_link_orb_command(scsi_id, command); - return 0; + return(0); +} + + +/* + * This function deals with command set differences between Linux scsi + * command set and sbp2 RBC command set. + */ +static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd) +{ + unchar new_cmd[16]; + u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun); + + SBP2_DEBUG("sbp2_check_sbp2_command"); + + switch (*cmd) { + + case READ_6: + + if (sbp2_command_conversion_device_type(device_type)) { + + SBP2_DEBUG("Convert READ_6 to READ_10"); + + /* + * Need to turn read_6 into read_10 + */ + new_cmd[0] = 0x28; + new_cmd[1] = (cmd[1] & 0xe0); + new_cmd[2] = 0x0; + new_cmd[3] = (cmd[1] & 0x1f); + new_cmd[4] = cmd[2]; + new_cmd[5] = cmd[3]; + new_cmd[6] = 0x0; + new_cmd[7] = 0x0; + new_cmd[8] = cmd[4]; + new_cmd[9] = cmd[5]; + + memcpy(cmd, new_cmd, 10); + + } + + break; + + case WRITE_6: + + if (sbp2_command_conversion_device_type(device_type)) { + + SBP2_DEBUG("Convert WRITE_6 to WRITE_10"); + + /* + * Need to turn write_6 into write_10 + */ + new_cmd[0] = 0x2a; + new_cmd[1] = (cmd[1] & 0xe0); + new_cmd[2] = 0x0; + new_cmd[3] = (cmd[1] & 0x1f); + new_cmd[4] = cmd[2]; + new_cmd[5] = cmd[3]; + new_cmd[6] = 0x0; + new_cmd[7] = 0x0; + new_cmd[8] = cmd[4]; + new_cmd[9] = cmd[5]; + + memcpy(cmd, new_cmd, 10); + + } + + break; + + case MODE_SENSE: + + if (sbp2_command_conversion_device_type(device_type)) { + + SBP2_DEBUG("Convert MODE_SENSE_6 to MODE_SENSE_10"); + + /* + * Need to turn mode_sense_6 into mode_sense_10 + */ + new_cmd[0] = 0x5a; + new_cmd[1] = cmd[1]; + new_cmd[2] = cmd[2]; + new_cmd[3] = 0x0; + new_cmd[4] = 0x0; + new_cmd[5] = 0x0; + new_cmd[6] = 0x0; + new_cmd[7] = 0x0; + new_cmd[8] = cmd[4]; + new_cmd[9] = cmd[5]; + + memcpy(cmd, new_cmd, 10); + + } + + break; + + case MODE_SELECT: + + /* + * TODO. Probably need to change mode select to 10 byte version + */ + + default: + break; + } + + return; } /* @@ -2068,40 +2260,80 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense sense_data[14] = sbp2_status[20]; sense_data[15] = sbp2_status[21]; - return sbp2_status[8] & 0x3f; /* return scsi status */ + return(sbp2_status[8] & 0x3f); /* return scsi status */ } /* * This function is called after a command is completed, in order to do any necessary SBP-2 * response data translations for the SCSI stack */ -static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, +static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, struct scsi_cmnd *SCpnt) { u8 *scsi_buf = SCpnt->request_buffer; + u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun); SBP2_DEBUG("sbp2_check_sbp2_response"); switch (SCpnt->cmnd[0]) { - case INQUIRY: - /* - * Make sure data length is ok. Minimum length is 36 bytes - */ - if (scsi_buf[4] == 0) { - scsi_buf[4] = 36 - 5; - } + case INQUIRY: - /* - * Fix ansi revision and response data format - */ - scsi_buf[2] |= 2; - scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2; + /* + * If scsi_id->sbp2_device_type_and_lun is uninitialized, then fill + * this information in from the inquiry response data. Lun is set to zero. + */ + if (scsi_id->sbp2_device_type_and_lun == SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) { + SBP2_DEBUG("Creating sbp2_device_type_and_lun from scsi inquiry data"); + scsi_id->sbp2_device_type_and_lun = (scsi_buf[0] & 0x1f) << 16; + } + + /* + * Make sure data length is ok. Minimum length is 36 bytes + */ + if (scsi_buf[4] == 0) { + scsi_buf[4] = 36 - 5; + } + + /* + * Check for Simple Direct Access Device and change it to TYPE_DISK + */ + if ((scsi_buf[0] & 0x1f) == TYPE_RBC) { + SBP2_DEBUG("Changing TYPE_RBC to TYPE_DISK"); + scsi_buf[0] &= 0xe0; + } + + /* + * Fix ansi revision and response data format + */ + scsi_buf[2] |= 2; + scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2; + + break; + + case MODE_SENSE: + + if (sbp2_command_conversion_device_type(device_type)) { + + SBP2_DEBUG("Modify mode sense response (10 byte version)"); + + scsi_buf[0] = scsi_buf[1]; /* Mode data length */ + scsi_buf[1] = scsi_buf[2]; /* Medium type */ + scsi_buf[2] = scsi_buf[3]; /* Device specific parameter */ + scsi_buf[3] = scsi_buf[7]; /* Block descriptor length */ + memcpy(scsi_buf + 4, scsi_buf + 8, scsi_buf[0]); + } + + break; - break; + case MODE_SELECT: - default: - break; + /* + * TODO. Probably need to change mode select to 10 byte version + */ + + default: + break; } return; } @@ -2126,14 +2358,14 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest if (!host) { SBP2_ERR("host is NULL - this is bad!"); - return RCODE_ADDRESS_ERROR; + return(RCODE_ADDRESS_ERROR); } hi = hpsb_get_hostinfo(&sbp2_highlevel, host); if (!hi) { SBP2_ERR("host info is NULL - this is bad!"); - return RCODE_ADDRESS_ERROR; + return(RCODE_ADDRESS_ERROR); } /* @@ -2150,7 +2382,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest if (!scsi_id) { SBP2_ERR("scsi_id is NULL - device is gone?"); - return RCODE_ADDRESS_ERROR; + return(RCODE_ADDRESS_ERROR); } /* @@ -2248,9 +2480,10 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest SBP2_ORB_DEBUG("command orb completed"); } - return RCODE_COMPLETE; + return(RCODE_COMPLETE); } + /************************************** * SCSI interface related section **************************************/ @@ -2307,16 +2540,6 @@ static int sbp2scsi_queuecommand(struct scsi_cmnd *SCpnt, goto done; } - /* - * Bidirectional commands are not yet implemented, - * and unknown transfer direction not handled. - */ - if (SCpnt->sc_data_direction == DMA_BIDIRECTIONAL) { - SBP2_ERR("Cannot handle DMA_BIDIRECTIONAL - rejecting command"); - result = DID_ERROR << 16; - goto done; - } - /* * Try and send our SCSI command */ @@ -2393,56 +2616,55 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, * complete the command, just let it get retried at the end of the * bus reset. */ - if (!hpsb_node_entry_valid(scsi_id->ne) - && (scsi_status != SBP2_SCSI_STATUS_GOOD)) { + if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) { SBP2_ERR("Bus reset in progress - retry command later"); return; } - + /* * Switch on scsi status */ switch (scsi_status) { - case SBP2_SCSI_STATUS_GOOD: - SCpnt->result = DID_OK; - break; + case SBP2_SCSI_STATUS_GOOD: + SCpnt->result = DID_OK; + break; - case SBP2_SCSI_STATUS_BUSY: - SBP2_ERR("SBP2_SCSI_STATUS_BUSY"); - SCpnt->result = DID_BUS_BUSY << 16; - break; + case SBP2_SCSI_STATUS_BUSY: + SBP2_ERR("SBP2_SCSI_STATUS_BUSY"); + SCpnt->result = DID_BUS_BUSY << 16; + break; - case SBP2_SCSI_STATUS_CHECK_CONDITION: - SBP2_DEBUG("SBP2_SCSI_STATUS_CHECK_CONDITION"); - SCpnt->result = CHECK_CONDITION << 1; + case SBP2_SCSI_STATUS_CHECK_CONDITION: + SBP2_DEBUG("SBP2_SCSI_STATUS_CHECK_CONDITION"); + SCpnt->result = CHECK_CONDITION << 1; - /* - * Debug stuff - */ + /* + * Debug stuff + */ #if CONFIG_IEEE1394_SBP2_DEBUG >= 1 - scsi_print_command(SCpnt); - scsi_print_sense("bh", SCpnt); + scsi_print_command(SCpnt); + scsi_print_sense("bh", SCpnt); #endif - break; + break; - case SBP2_SCSI_STATUS_SELECTION_TIMEOUT: - SBP2_ERR("SBP2_SCSI_STATUS_SELECTION_TIMEOUT"); - SCpnt->result = DID_NO_CONNECT << 16; - scsi_print_command(SCpnt); - break; + case SBP2_SCSI_STATUS_SELECTION_TIMEOUT: + SBP2_ERR("SBP2_SCSI_STATUS_SELECTION_TIMEOUT"); + SCpnt->result = DID_NO_CONNECT << 16; + scsi_print_command(SCpnt); + break; - case SBP2_SCSI_STATUS_CONDITION_MET: - case SBP2_SCSI_STATUS_RESERVATION_CONFLICT: - case SBP2_SCSI_STATUS_COMMAND_TERMINATED: - SBP2_ERR("Bad SCSI status = %x", scsi_status); - SCpnt->result = DID_ERROR << 16; - scsi_print_command(SCpnt); - break; + case SBP2_SCSI_STATUS_CONDITION_MET: + case SBP2_SCSI_STATUS_RESERVATION_CONFLICT: + case SBP2_SCSI_STATUS_COMMAND_TERMINATED: + SBP2_ERR("Bad SCSI status = %x", scsi_status); + SCpnt->result = DID_ERROR << 16; + scsi_print_command(SCpnt); + break; - default: - SBP2_ERR("Unsupported SCSI status = %x", scsi_status); - SCpnt->result = DID_ERROR << 16; + default: + SBP2_ERR("Unsupported SCSI status = %x", scsi_status); + SCpnt->result = DID_ERROR << 16; } /* @@ -2456,8 +2678,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, * If a bus reset is in progress and there was an error, complete * the command as busy so that it will get retried. */ - if (!hpsb_node_entry_valid(scsi_id->ne) - && (scsi_status != SBP2_SCSI_STATUS_GOOD)) { + if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) { SBP2_ERR("Completing command with busy (bus reset)"); SCpnt->result = DID_BUS_BUSY << 16; } @@ -2478,29 +2699,31 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, /* * Tell scsi stack that we're done with this command */ - done(SCpnt); + done (SCpnt); } + static int sbp2scsi_slave_alloc(struct scsi_device *sdev) { ((struct scsi_id_instance_data *)sdev->host->hostdata[0])->sdev = sdev; return 0; } + static int sbp2scsi_slave_configure(struct scsi_device *sdev) { blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); - sdev->use_10_for_rw = 1; - sdev->use_10_for_ms = 1; return 0; } + static void sbp2scsi_slave_destroy(struct scsi_device *sdev) { ((struct scsi_id_instance_data *)sdev->host->hostdata[0])->sdev = NULL; return; } + /* * Called by scsi stack when something has really gone wrong. Usually * called when a command has timed-out for some reason. @@ -2546,7 +2769,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt) sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY); } - return SUCCESS; + return(SUCCESS); } /* @@ -2556,20 +2779,28 @@ static int sbp2scsi_reset(struct scsi_cmnd *SCpnt) { struct scsi_id_instance_data *scsi_id = (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; + unsigned long flags; SBP2_ERR("reset requested"); + spin_lock_irqsave(SCpnt->device->host->host_lock, flags); + if (sbp2util_node_is_available(scsi_id)) { SBP2_ERR("Generating sbp2 fetch agent reset"); sbp2_agent_reset(scsi_id, 0); } + spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); + return SUCCESS; } -static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static const char *sbp2scsi_info (struct Scsi_Host *host) +{ + return "SCSI emulation for IEEE-1394 SBP-2 Devices"; +} + +static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_device *sdev; struct scsi_id_instance_data *scsi_id; @@ -2581,7 +2812,10 @@ static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, if (!(scsi_id = (struct scsi_id_instance_data *)sdev->host->hostdata[0])) return 0; - lun = ORB_SET_LUN(scsi_id->sbp2_lun); + if (scsi_id->sbp2_device_type_and_lun == SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) + lun = 0; + else + lun = ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun); return sprintf(buf, "%016Lx:%d:%d\n", (unsigned long long)scsi_id->ne->guid, scsi_id->ud->id, lun); @@ -2603,9 +2837,12 @@ static struct scsi_host_template scsi_driver_template = { .module = THIS_MODULE, .name = "SBP-2 IEEE-1394", .proc_name = SBP2_DEVICE_NAME, + .info = sbp2scsi_info, .queuecommand = sbp2scsi_queuecommand, .eh_abort_handler = sbp2scsi_abort, .eh_device_reset_handler = sbp2scsi_reset, + .eh_bus_reset_handler = sbp2scsi_reset, + .eh_host_reset_handler = sbp2scsi_reset, .slave_alloc = sbp2scsi_slave_alloc, .slave_configure = sbp2scsi_slave_configure, .slave_destroy = sbp2scsi_slave_destroy, @@ -2624,6 +2861,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_INFO("Driver forced to serialize I/O (serialize_io=1)"); @@ -2635,6 +2874,7 @@ static int sbp2_module_init(void) /* Set max sectors (module load option). Default is 255 sectors. */ scsi_driver_template.max_sectors = max_sectors; + /* Register our high level driver with 1394 stack */ hpsb_register_highlevel(&sbp2_highlevel); diff --git a/trunk/drivers/ieee1394/sbp2.h b/trunk/drivers/ieee1394/sbp2.h index 900ea1d25e71..cd425be74841 100644 --- a/trunk/drivers/ieee1394/sbp2.h +++ b/trunk/drivers/ieee1394/sbp2.h @@ -119,8 +119,8 @@ struct sbp2_query_logins_response { struct sbp2_reconnect_orb { u32 reserved1; u32 reserved2; - u32 reserved3; - u32 reserved4; + u32 reserved3; + u32 reserved4; u32 login_ID_misc; u32 reserved5; u32 status_FIFO_hi; @@ -130,8 +130,8 @@ struct sbp2_reconnect_orb { struct sbp2_logout_orb { u32 reserved1; u32 reserved2; - u32 reserved3; - u32 reserved4; + u32 reserved3; + u32 reserved4; u32 login_ID_misc; u32 reserved5; u32 status_FIFO_hi; @@ -188,7 +188,7 @@ struct sbp2_unrestricted_page_table { struct sbp2_status_block { u32 ORB_offset_hi_misc; u32 ORB_offset_lo; - u8 command_set_dependent[24]; + u8 command_set_dependent[24]; }; /* @@ -211,7 +211,7 @@ struct sbp2_status_block { * specified for write posting, where the ohci controller will * automatically send an ack_complete when the status is written by the * sbp2 device... saving a split transaction. =) - */ + */ #define SBP2_STATUS_FIFO_ADDRESS 0xfffe00000000ULL #define SBP2_STATUS_FIFO_ADDRESS_HI 0xfffe #define SBP2_STATUS_FIFO_ADDRESS_LO 0x0 @@ -229,6 +229,9 @@ struct sbp2_status_block { #define SBP2_DEVICE_TYPE_AND_LUN_KEY 0x14 #define SBP2_FIRMWARE_REVISION_KEY 0x3c +#define SBP2_DEVICE_TYPE(q) (((q) >> 16) & 0x1f) +#define SBP2_DEVICE_LUN(q) ((q) & 0xffff) + #define SBP2_AGENT_STATE_OFFSET 0x00ULL #define SBP2_AGENT_RESET_OFFSET 0x04ULL #define SBP2_ORB_POINTER_OFFSET 0x08ULL @@ -253,6 +256,8 @@ struct sbp2_status_block { */ #define SBP2_128KB_BROKEN_FIRMWARE 0xa0b800 +#define SBP2_DEVICE_TYPE_LUN_UNINITIALIZED 0xffffffff + /* * SCSI specific stuff */ @@ -260,7 +265,45 @@ struct sbp2_status_block { #define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000 #define SBP2_MAX_UDS_PER_NODE 16 /* Maximum scsi devices per node */ #define SBP2_MAX_SECTORS 255 /* Max sectors supported */ -#define SBP2_MAX_CMDS 8 /* This should be safe */ + +/* + * SCSI direction table... + * (now used as a back-up in case the direction passed down from above is "unknown") + * + * DIN = IN data direction + * DOU = OUT data direction + * DNO = No data transfer + * DUN = Unknown data direction + * + * Opcode 0xec (Teac specific "opc execute") possibly should be DNO, + * but we'll change it when somebody reports a problem with this. + */ +#define DIN ORB_DIRECTION_READ_FROM_MEDIA +#define DOU ORB_DIRECTION_WRITE_TO_MEDIA +#define DNO ORB_DIRECTION_NO_DATA_TRANSFER +#define DUN DIN + +static unchar sbp2scsi_direction_table[0x100] = { + DNO,DNO,DIN,DIN,DOU,DIN,DIN,DOU,DIN,DUN,DOU,DOU,DUN,DUN,DUN,DIN, + DNO,DIN,DIN,DOU,DIN,DOU,DNO,DNO,DOU,DNO,DIN,DNO,DIN,DOU,DNO,DUN, + DIN,DUN,DIN,DIN,DOU,DIN,DUN,DUN,DIN,DIN,DOU,DNO,DUN,DIN,DOU,DOU, + DOU,DOU,DOU,DNO,DIN,DNO,DNO,DIN,DOU,DOU,DOU,DOU,DIN,DOU,DIN,DOU, + DOU,DOU,DIN,DIN,DIN,DNO,DIN,DNO,DNO,DNO,DUN,DNO,DOU,DIN,DNO,DUN, + DUN,DIN,DIN,DNO,DNO,DOU,DUN,DUN,DNO,DIN,DIN,DNO,DIN,DOU,DUN,DUN, + DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, + DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, + DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, + DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, + DUN,DNO,DOU,DOU,DIN,DNO,DNO,DNO,DIN,DNO,DOU,DUN,DNO,DIN,DOU,DOU, + DOU,DOU,DOU,DNO,DUN,DIN,DOU,DIN,DIN,DIN,DNO,DNO,DNO,DIN,DIN,DUN, + DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, + DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, + DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN, + DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN +}; + +/* This should be safe */ +#define SBP2_MAX_CMDS 8 /* This is the two dma types we use for cmd_dma below */ enum cmd_dma_types { @@ -295,8 +338,10 @@ struct sbp2_command_info { #define SBP2_BREAKAGE_128K_MAX_TRANSFER 0x1 #define SBP2_BREAKAGE_INQUIRY_HACK 0x2 + struct sbp2scsi_host_info; + /* * Information needed on a per scsi id basis (one for each sbp2 device) */ @@ -334,7 +379,7 @@ struct scsi_id_instance_data { u32 sbp2_command_set_spec_id; u32 sbp2_command_set; u32 sbp2_unit_characteristics; - u32 sbp2_lun; + u32 sbp2_device_type_and_lun; u32 sbp2_firmware_revision; /* @@ -366,6 +411,7 @@ struct scsi_id_instance_data { u32 workarounds; }; + /* Sbp2 host data structure (one per IEEE1394 host) */ struct sbp2scsi_host_info { struct hpsb_host *host; /* IEEE1394 host */ @@ -410,12 +456,20 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id); static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data, u64 addr, size_t length, u16 flags); static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait); +static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id, + struct sbp2_command_info *command, + unchar *scsi_cmd, + unsigned int scsi_use_sg, + unsigned int scsi_request_bufflen, + void *scsi_request_buffer, + enum dma_data_direction dma_dir); static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, struct sbp2_command_info *command); static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data); +static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd); static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, struct scsi_cmnd *SCpnt); static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, diff --git a/trunk/drivers/ieee1394/video1394.c b/trunk/drivers/ieee1394/video1394.c index 608479b2df14..23911da50154 100644 --- a/trunk/drivers/ieee1394/video1394.c +++ b/trunk/drivers/ieee1394/video1394.c @@ -19,6 +19,12 @@ * * NOTES: * + * jds -- add private data to file to keep track of iso contexts associated + * with each open -- so release won't kill all iso transfers. + * + * Damien Douxchamps: Fix failure when the number of DMA pages per frame is + * one. + * * ioctl return codes: * EFAULT is only for invalid address for the argp * EINVAL for out of range values @@ -28,6 +34,12 @@ * ENOTTY for unsupported ioctl request * */ + +/* Markus Tavenrath : + - fixed checks for valid buffer-numbers in video1394_icotl + - changed the ways the dma prg's are used, now it's possible to use + even a single dma buffer +*/ #include #include #include @@ -65,6 +77,14 @@ #define ISO_CHANNELS 64 +#ifndef virt_to_page +#define virt_to_page(x) MAP_NR(x) +#endif + +#ifndef vmalloc_32 +#define vmalloc_32(x) vmalloc(x) +#endif + struct it_dma_prg { struct dma_cmd begin; quadlet_t data[4]; @@ -186,12 +206,14 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, struct dma_iso_ctx *d; int i; - d = kzalloc(sizeof(*d), GFP_KERNEL); - if (!d) { + d = kmalloc(sizeof(struct dma_iso_ctx), GFP_KERNEL); + if (d == NULL) { PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma_iso_ctx"); return NULL; } + memset(d, 0, sizeof *d); + d->ohci = ohci; d->type = type; d->channel = channel; @@ -229,8 +251,9 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, } d->ctx = d->iso_tasklet.context; - d->prg_reg = kmalloc(d->num_desc * sizeof(*d->prg_reg), GFP_KERNEL); - if (!d->prg_reg) { + d->prg_reg = kmalloc(d->num_desc * sizeof(struct dma_prog_region), + GFP_KERNEL); + if (d->prg_reg == NULL) { PRINT(KERN_ERR, ohci->host->id, "Failed to allocate ir prg regs"); free_dma_iso_ctx(d); return NULL; @@ -245,14 +268,15 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, d->cmdPtr = OHCI1394_IsoRcvCommandPtr+32*d->ctx; d->ctxMatch = OHCI1394_IsoRcvContextMatch+32*d->ctx; - d->ir_prg = kzalloc(d->num_desc * sizeof(*d->ir_prg), + d->ir_prg = kmalloc(d->num_desc * sizeof(struct dma_cmd *), GFP_KERNEL); - if (!d->ir_prg) { + if (d->ir_prg == NULL) { PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma ir prg"); free_dma_iso_ctx(d); return NULL; } + memset(d->ir_prg, 0, d->num_desc * sizeof(struct dma_cmd *)); d->nb_cmd = d->buf_size / PAGE_SIZE + 1; d->left_size = (d->frame_size % PAGE_SIZE) ? @@ -273,15 +297,16 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, d->ctrlClear = OHCI1394_IsoXmitContextControlClear+16*d->ctx; d->cmdPtr = OHCI1394_IsoXmitCommandPtr+16*d->ctx; - d->it_prg = kzalloc(d->num_desc * sizeof(*d->it_prg), + d->it_prg = kmalloc(d->num_desc * sizeof(struct it_dma_prg *), GFP_KERNEL); - if (!d->it_prg) { + if (d->it_prg == NULL) { PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma it prg"); free_dma_iso_ctx(d); return NULL; } + memset(d->it_prg, 0, d->num_desc*sizeof(struct it_dma_prg *)); d->packet_size = packet_size; @@ -312,24 +337,47 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, } } - d->buffer_status = - kzalloc(d->num_desc * sizeof(*d->buffer_status), GFP_KERNEL); - d->buffer_prg_assignment = - kzalloc(d->num_desc * sizeof(*d->buffer_prg_assignment), GFP_KERNEL); - d->buffer_time = - kzalloc(d->num_desc * sizeof(*d->buffer_time), GFP_KERNEL); - d->last_used_cmd = - kzalloc(d->num_desc * sizeof(*d->last_used_cmd), GFP_KERNEL); - d->next_buffer = - kzalloc(d->num_desc * sizeof(*d->next_buffer), GFP_KERNEL); - - if (!d->buffer_status || !d->buffer_prg_assignment || !d->buffer_time || - !d->last_used_cmd || !d->next_buffer) { - PRINT(KERN_ERR, ohci->host->id, - "Failed to allocate dma_iso_ctx member"); + d->buffer_status = kmalloc(d->num_desc * sizeof(unsigned int), + GFP_KERNEL); + d->buffer_prg_assignment = kmalloc(d->num_desc * sizeof(unsigned int), + GFP_KERNEL); + d->buffer_time = kmalloc(d->num_desc * sizeof(struct timeval), + GFP_KERNEL); + d->last_used_cmd = kmalloc(d->num_desc * sizeof(unsigned int), + GFP_KERNEL); + d->next_buffer = kmalloc(d->num_desc * sizeof(int), + GFP_KERNEL); + + if (d->buffer_status == NULL) { + PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_status"); + free_dma_iso_ctx(d); + return NULL; + } + if (d->buffer_prg_assignment == NULL) { + PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_prg_assignment"); + free_dma_iso_ctx(d); + return NULL; + } + if (d->buffer_time == NULL) { + PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_time"); + free_dma_iso_ctx(d); + return NULL; + } + if (d->last_used_cmd == NULL) { + PRINT(KERN_ERR, ohci->host->id, "Failed to allocate last_used_cmd"); + free_dma_iso_ctx(d); + return NULL; + } + if (d->next_buffer == NULL) { + PRINT(KERN_ERR, ohci->host->id, "Failed to allocate next_buffer"); free_dma_iso_ctx(d); return NULL; } + memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int)); + memset(d->buffer_prg_assignment, 0, d->num_desc * sizeof(unsigned int)); + memset(d->buffer_time, 0, d->num_desc * sizeof(struct timeval)); + memset(d->last_used_cmd, 0, d->num_desc * sizeof(unsigned int)); + memset(d->next_buffer, -1, d->num_desc * sizeof(int)); spin_lock_init(&d->lock); @@ -491,7 +539,7 @@ static void wakeup_dma_ir_ctx(unsigned long l) if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) { reset_ir_status(d, i); d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY; - do_gettimeofday(&d->buffer_time[d->buffer_prg_assignment[i]]); + do_gettimeofday(&d->buffer_time[i]); } } @@ -998,6 +1046,7 @@ static int __video1394_ioctl(struct file *file, /* set time of buffer */ v.filltime = d->buffer_time[v.buffer]; +// printk("Buffer %d time %d\n", v.buffer, (d->buffer_time[v.buffer]).tv_usec); /* * Look ahead to see how many more buffers have been received @@ -1036,7 +1085,7 @@ static int __video1394_ioctl(struct file *file, } if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { - int buf_size = d->nb_cmd * sizeof(*psizes); + int buf_size = d->nb_cmd * sizeof(unsigned int); struct video1394_queue_variable __user *p = argp; unsigned int __user *qv; @@ -1055,7 +1104,7 @@ static int __video1394_ioctl(struct file *file, spin_lock_irqsave(&d->lock,flags); - /* last_buffer is last_prg */ + // last_buffer is last_prg next_prg = (d->last_buffer + 1) % d->num_desc; if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) { PRINT(KERN_ERR, ohci->host->id, @@ -1202,12 +1251,13 @@ static int video1394_open(struct inode *inode, struct file *file) if (ohci == NULL) return -EIO; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) { + ctx = kmalloc(sizeof(struct file_ctx), GFP_KERNEL); + if (ctx == NULL) { PRINT(KERN_ERR, ohci->host->id, "Cannot malloc file_ctx"); return -ENOMEM; } + memset(ctx, 0, sizeof(struct file_ctx)); ctx->ohci = ohci; INIT_LIST_HEAD(&ctx->context_list); ctx->current_ctx = NULL; diff --git a/trunk/net/ipv4/ipvs/ip_vs_est.c b/trunk/net/ipv4/ipvs/ip_vs_est.c index e7004741ac73..c453e1e57f4b 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_est.c +++ b/trunk/net/ipv4/ipvs/ip_vs_est.c @@ -18,6 +18,7 @@ #include #include #include +#include #include diff --git a/trunk/net/ipv4/ipvs/ip_vs_sched.c b/trunk/net/ipv4/ipvs/ip_vs_sched.c index 0f7c56a225bd..8bc42b76223d 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_sched.c +++ b/trunk/net/ipv4/ipvs/ip_vs_sched.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include