From: Ben Collins ChangeSet@1.1534, 2003-12-24 10:17:28-05:00, bcollins@debian.org Many files: IEEE-1394 Sync with r1088 - Cleanup Kconfig so that ieee1394 core doesn't require PCI. - Some function renames to make things consistent. - Fixup ISO API so that packet-per-buffer and irq-interval work correctly. - Get rid of host list and use driver model for handling host ref count and host accounting. - Get rid of packet semaphore. - Move bus registration into core ieee1394 initialization. - Get rid of ancient unused data_be (big-endian) flag in packet struct. - Fix recursive use of bus_for_each_dev() in nodemgr. - Revert changes to oui.db. This file is verbatim from IEEE, so if any changes should be made, register them with the IEEE database and keep this one pristine. - Fix PCILynx so that it checks for errors on calls to copy_from_user(). - Add ARM API handlers to raw1394. - Cleanup sbp2's packet sending to accomodate for a case where a packet was free'd while sbp2 was waiting on it. drivers/ieee1394/Kconfig | 20 ++-- drivers/ieee1394/eth1394.c | 16 +-- drivers/ieee1394/highlevel.c | 44 +++++----- drivers/ieee1394/highlevel.h | 5 - drivers/ieee1394/hosts.c | 104 +++++-------------------- drivers/ieee1394/hosts.h | 22 ----- drivers/ieee1394/ieee1394_core.c | 120 +++++++++++++++-------------- drivers/ieee1394/ieee1394_core.h | 24 ++--- drivers/ieee1394/ieee1394_transactions.c | 69 +++++++--------- drivers/ieee1394/iso.c | 16 ++- drivers/ieee1394/iso.h | 11 ++ drivers/ieee1394/nodemgr.c | 88 +++++++++++---------- drivers/ieee1394/nodemgr.h | 9 ++ drivers/ieee1394/ohci1394.c | 51 +++++++----- drivers/ieee1394/oui.db | 6 - drivers/ieee1394/pcilynx.c | 30 ++++--- drivers/ieee1394/raw1394.c | 126 ++++++++++++++++++++++++++++-- drivers/ieee1394/raw1394.h | 5 + drivers/ieee1394/sbp2.c | 127 +++++++++++-------------------- 19 files changed, 470 insertions(+), 423 deletions(-) diff -puN drivers/ieee1394/eth1394.c~ieee1394-update drivers/ieee1394/eth1394.c --- 25/drivers/ieee1394/eth1394.c~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/eth1394.c 2003-12-24 10:25:54.000000000 -0800 @@ -89,7 +89,7 @@ #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) static char version[] __devinitdata = - "$Rev: 1043 $ Ben Collins "; + "$Rev: 1079 $ Ben Collins "; struct fragment_info { struct list_head list; @@ -220,7 +220,7 @@ static int ether1394_init_bc(struct net_ priv->iso = hpsb_iso_recv_init(priv->host, 16 * 4096, 16, priv->broadcast_channel, - 1, ether1394_iso); + HPSB_ISO_DMA_PACKET_PER_BUFFER, 1, ether1394_iso); if (priv->iso == NULL) { ETH1394_PRINT(KERN_ERR, dev->name, "failed to change broadcast " @@ -475,7 +475,7 @@ static void ether1394_add_host (struct h priv->broadcast_channel = host->csr.broadcast_channel & 0x3f; priv->iso = hpsb_iso_recv_init(host, 16 * 4096, 16, priv->broadcast_channel, - 1, ether1394_iso); + HPSB_ISO_DMA_PACKET_PER_BUFFER, 1, ether1394_iso); if (priv->iso == NULL) { priv->bc_state = ETHER1394_BC_CLOSED; } @@ -1258,7 +1258,7 @@ static inline struct hpsb_packet *ether1 { struct hpsb_packet *p; - p = alloc_hpsb_packet(0); + p = hpsb_alloc_packet(0); if (p) { p->host = host; p->data = NULL; @@ -1327,7 +1327,7 @@ static inline void ether1394_free_packet if (packet->tcode != TCODE_STREAM_DATA) hpsb_free_tlabel(packet); packet->data = NULL; - free_hpsb_packet(packet); + hpsb_free_packet(packet); } static void ether1394_complete_cb(void *__ptask); @@ -1349,7 +1349,7 @@ static int ether1394_send_packet(struct ptask->dest_node, ptask->addr, ptask->skb->data, tx_len)) { - free_hpsb_packet(packet); + hpsb_free_packet(packet); return -1; } @@ -1357,7 +1357,7 @@ static int ether1394_send_packet(struct hpsb_set_packet_complete_task(ptask->packet, ether1394_complete_cb, ptask); - if (!hpsb_send_packet(packet)) { + if (hpsb_send_packet(packet) < 0) { ether1394_free_packet(packet); return -1; } @@ -1599,7 +1599,7 @@ static int ether1394_ethtool_ioctl(struc case ETHTOOL_GDRVINFO: { struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; strcpy (info.driver, driver_name); - strcpy (info.version, "$Rev: 1043 $"); + strcpy (info.version, "$Rev: 1079 $"); /* FIXME XXX provide sane businfo */ strcpy (info.bus_info, "ieee1394"); if (copy_to_user (useraddr, &info, sizeof (info))) diff -puN drivers/ieee1394/highlevel.c~ieee1394-update drivers/ieee1394/highlevel.c --- 25/drivers/ieee1394/highlevel.c~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/highlevel.c 2003-12-24 10:25:54.000000000 -0800 @@ -26,6 +26,7 @@ #include "hosts.h" #include "ieee1394_core.h" #include "highlevel.h" +#include "nodemgr.h" struct hl_host_info { @@ -227,10 +228,17 @@ struct hpsb_host *hpsb_get_host_bykey(st return host; } +static int highlevel_for_each_host_reg(struct hpsb_host *host, void *__data) +{ + struct hpsb_highlevel *hl = __data; + + hl->add_host(host); + + return 0; +} void hpsb_register_highlevel(struct hpsb_highlevel *hl) { - struct list_head *lh; unsigned long flags; INIT_LIST_HEAD(&hl->addr_list); @@ -242,21 +250,25 @@ void hpsb_register_highlevel(struct hpsb list_add_tail(&hl->hl_list, &hl_drivers); write_unlock_irqrestore(&hl_drivers_lock, flags); - if (hl->add_host) { - down(&hpsb_hosts_lock); - list_for_each (lh, &hpsb_hosts) { - struct hpsb_host *host = list_entry(lh, struct hpsb_host, host_list); - hl->add_host(host); - } - up(&hpsb_hosts_lock); - } + if (hl->add_host) + nodemgr_for_each_host(hl, highlevel_for_each_host_reg); return; } +static int highlevel_for_each_host_unreg(struct hpsb_host *host, void *__data) +{ + struct hpsb_highlevel *hl = __data; + + hl->remove_host(host); + hpsb_destroy_hostinfo(hl, host); + + return 0; +} + void hpsb_unregister_highlevel(struct hpsb_highlevel *hl) { - struct list_head *lh, *next; + struct list_head *lh, *next; struct hpsb_address_serve *as; unsigned long flags; @@ -272,16 +284,8 @@ void hpsb_unregister_highlevel(struct hp list_del(&hl->hl_list); write_unlock_irqrestore(&hl_drivers_lock, flags); - if (hl->remove_host) { - down(&hpsb_hosts_lock); - list_for_each(lh, &hpsb_hosts) { - struct hpsb_host *host = list_entry(lh, struct hpsb_host, host_list); - - hl->remove_host(host); - hpsb_destroy_hostinfo(hl, host); - } - up(&hpsb_hosts_lock); - } + if (hl->remove_host) + nodemgr_for_each_host(hl, highlevel_for_each_host_unreg); } int hpsb_register_addrspace(struct hpsb_highlevel *hl, diff -puN drivers/ieee1394/highlevel.h~ieee1394-update drivers/ieee1394/highlevel.h --- 25/drivers/ieee1394/highlevel.h~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/highlevel.h 2003-12-24 10:25:54.000000000 -0800 @@ -92,8 +92,6 @@ struct hpsb_address_ops { }; -void init_hpsb_highlevel(void); - void highlevel_add_host(struct hpsb_host *host); void highlevel_remove_host(struct hpsb_host *host); void highlevel_host_reset(struct hpsb_host *host); @@ -180,4 +178,7 @@ int hpsb_set_hostinfo(struct hpsb_highle /* Retrieve hpsb_host using a highlevel handle and a key */ struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key); +/* Initialize the highlevel system */ +void init_hpsb_highlevel(void); + #endif /* IEEE1394_HIGHLEVEL_H */ diff -puN drivers/ieee1394/hosts.c~ieee1394-update drivers/ieee1394/hosts.c --- 25/drivers/ieee1394/hosts.c~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/hosts.c 2003-12-24 10:25:54.000000000 -0800 @@ -16,14 +16,14 @@ #include #include #include +#include #include "ieee1394_types.h" #include "hosts.h" #include "ieee1394_core.h" #include "highlevel.h" +#include "nodemgr.h" -LIST_HEAD(hpsb_hosts); -DECLARE_MUTEX(hpsb_hosts_lock); static int dummy_transmit_packet(struct hpsb_host *h, struct hpsb_packet *p) { @@ -46,54 +46,14 @@ static struct hpsb_host_driver dummy_dri .isoctl = dummy_isoctl }; -/** - * hpsb_ref_host - increase reference count for host controller. - * @host: the host controller - * - * Increase the reference count for the specified host controller. - * When holding a reference to a host, the memory allocated for the - * host struct will not be freed and the host is guaranteed to be in a - * consistent state. The driver may be unloaded or the controller may - * be removed (PCMCIA), but the host struct will remain valid. - */ - -int hpsb_ref_host(struct hpsb_host *host) +static int alloc_hostnum_cb(struct hpsb_host *host, void *__data) { - struct list_head *lh; - int retval = 0; - - down(&hpsb_hosts_lock); - list_for_each(lh, &hpsb_hosts) { - if (host == list_entry(lh, struct hpsb_host, host_list)) { - if (try_module_get(host->driver->owner)) { - atomic_inc(&host->refcount); - retval = 1; - } - break; - } - } - up(&hpsb_hosts_lock); - - return retval; -} + int *hostnum = __data; -/** - * hpsb_unref_host - decrease reference count for host controller. - * @host: the host controller - * - * Decrease the reference count for the specified host controller. - * When the reference count reaches zero, the memory allocated for the - * &hpsb_host will be freed. - */ - -void hpsb_unref_host(struct hpsb_host *host) -{ - module_put(host->driver->owner); + if (host->id == *hostnum) + return 1; - down(&hpsb_hosts_lock); - if (atomic_dec_and_test(&host->refcount) && host->is_shutdown) - device_unregister(&host->device); - up(&hpsb_hosts_lock); + return 0; } /** @@ -108,19 +68,16 @@ void hpsb_unref_host(struct hpsb_host *h * driver specific parts, enable the controller and make it available * to the general subsystem using hpsb_add_host(). * - * The &hpsb_host is allocated with an single initial reference - * belonging to the driver. Once the driver is done with the struct, - * for example, when the driver is unloaded, it should release this - * reference using hpsb_unref_host(). - * * Return Value: a pointer to the &hpsb_host if succesful, %NULL if * no memory was available. */ -struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra) +struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, + struct device *dev) { struct hpsb_host *h; int i; + int hostnum = 0; h = kmalloc(sizeof(struct hpsb_host) + extra, SLAB_KERNEL); if (!h) return NULL; @@ -128,7 +85,6 @@ struct hpsb_host *hpsb_alloc_host(struct h->hostdata = h + 1; h->driver = drv; - atomic_set(&h->refcount, 1); INIT_LIST_HEAD(&h->pending_packets); spin_lock_init(&h->pending_pkt_lock); @@ -146,53 +102,35 @@ struct hpsb_host *hpsb_alloc_host(struct h->topology_map = h->csr.topology_map + 3; h->speed_map = (u8 *)(h->csr.speed_map + 2); - return h; -} - -static int alloc_hostnum(void) -{ - int hostnum = 0; - while (1) { - struct list_head *lh; - int found = 0; - - list_for_each(lh, &hpsb_hosts) { - struct hpsb_host *host = list_entry(lh, struct hpsb_host, host_list); - - if (host->id == hostnum) { - found = 1; - break; - } + if (!nodemgr_for_each_host(&hostnum, alloc_hostnum_cb)) { + h->id = hostnum; + break; } - if (!found) - return hostnum; - hostnum++; } - return 0; + memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device)); + h->device.parent = dev; + snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); + device_register(&h->device); + + return h; } void hpsb_add_host(struct hpsb_host *host) { - down(&hpsb_hosts_lock); - host->id = alloc_hostnum(); - list_add_tail(&host->host_list, &hpsb_hosts); - up(&hpsb_hosts_lock); - highlevel_add_host(host); host->driver->devctl(host, RESET_BUS, LONG_RESET); } void hpsb_remove_host(struct hpsb_host *host) { - down(&hpsb_hosts_lock); host->is_shutdown = 1; host->driver = &dummy_driver; - list_del(&host->host_list); - up(&hpsb_hosts_lock); highlevel_remove_host(host); + + device_unregister(&host->device); } diff -puN drivers/ieee1394/hosts.h~ieee1394-update drivers/ieee1394/hosts.h --- 25/drivers/ieee1394/hosts.h~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/hosts.h 2003-12-24 10:25:54.000000000 -0800 @@ -29,8 +29,6 @@ struct hpsb_host { atomic_t generation; - atomic_t refcount; - struct list_head pending_packets; spinlock_t pending_pkt_lock; struct timer_list timeout; @@ -165,7 +163,7 @@ struct hpsb_host_driver { * 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 for failure. + * 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, @@ -195,22 +193,8 @@ struct hpsb_host_driver { }; -extern struct list_head hpsb_hosts; -extern struct semaphore hpsb_hosts_lock; - - -/* - * In order to prevent hosts from unloading, use hpsb_ref_host(). This prevents - * the host from going away (e.g. makes module unloading of the driver - * impossible), but still can not guarantee it (e.g. PC-Card being pulled by the - * user). hpsb_ref_host() returns false if host could not be locked. If it is - * successful, host is valid as a pointer until hpsb_unref_host() (not just - * until after remove_host). - */ -int hpsb_ref_host(struct hpsb_host *host); -void hpsb_unref_host(struct hpsb_host *host); - -struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra); +struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, + struct device *dev); void hpsb_add_host(struct hpsb_host *host); void hpsb_remove_host(struct hpsb_host *h); diff -puN drivers/ieee1394/ieee1394_core.c~ieee1394-update drivers/ieee1394/ieee1394_core.c --- 25/drivers/ieee1394/ieee1394_core.c~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/ieee1394_core.c 2003-12-24 10:25:54.000000000 -0800 @@ -109,7 +109,7 @@ void hpsb_set_packet_complete_task(struc } /** - * alloc_hpsb_packet - allocate new packet structure + * hpsb_alloc_packet - allocate new packet structure * @data_size: size of the data block to be allocated * * This function allocates, initializes and returns a new &struct hpsb_packet. @@ -128,7 +128,7 @@ void hpsb_set_packet_complete_task(struc * Return value: A pointer to a &struct hpsb_packet or NULL on allocation * failure. */ -struct hpsb_packet *alloc_hpsb_packet(size_t data_size) +struct hpsb_packet *hpsb_alloc_packet(size_t data_size) { struct hpsb_packet *packet = NULL; void *data = NULL; @@ -152,25 +152,23 @@ struct hpsb_packet *alloc_hpsb_packet(si } INIT_LIST_HEAD(&packet->list); - sema_init(&packet->state_change, 0); packet->complete_routine = NULL; packet->complete_data = NULL; packet->state = hpsb_unused; packet->generation = -1; - packet->data_be = 1; return packet; } /** - * free_hpsb_packet - free packet and data associated with it + * hpsb_free_packet - free packet and data associated with it * @packet: packet to free (is NULL safe) * * This function will free packet->data, packet->header and finally the packet * itself. */ -void free_hpsb_packet(struct hpsb_packet *packet) +void hpsb_free_packet(struct hpsb_packet *packet) { if (!packet) return; @@ -420,14 +418,12 @@ void hpsb_packet_sent(struct hpsb_host * if (packet->no_waiter) { /* must not have a tlabel allocated */ - free_hpsb_packet(packet); + hpsb_free_packet(packet); return; } if (ackcode != ACK_PENDING || !packet->expect_response) { packet->state = hpsb_complete; - up(&packet->state_change); - up(&packet->state_change); run_packet_complete(packet); return; } @@ -439,7 +435,6 @@ void hpsb_packet_sent(struct hpsb_host * list_add_tail(&packet->list, &host->pending_packets); spin_unlock_irqrestore(&host->pending_pkt_lock, flags); - up(&packet->state_change); mod_timer(&host->timeout, jiffies + host->timeout_interval); } @@ -465,7 +460,7 @@ int hpsb_send_phy_config(struct hpsb_hos return -EINVAL; } - packet = alloc_hpsb_packet(0); + packet = hpsb_alloc_packet(0); if (!packet) return -ENOMEM; @@ -485,16 +480,8 @@ int hpsb_send_phy_config(struct hpsb_hos packet->generation = get_hpsb_generation(host); - if (!hpsb_send_packet(packet)) { - retval = -EINVAL; - goto fail; - } - - down(&packet->state_change); - down(&packet->state_change); - -fail: - free_hpsb_packet(packet); + retval = hpsb_send_packet_and_wait(packet); + hpsb_free_packet(packet); return retval; } @@ -504,23 +491,24 @@ fail: * @packet: packet to send * * The packet is sent through the host specified in the packet->host field. - * Before sending, the packet's transmit speed is automatically determined using - * the local speed map when it is an async, non-broadcast packet. + * Before sending, the packet's transmit speed is automatically determined + * using the local speed map when it is an async, non-broadcast packet. * * Possibilities for failure are that host is either not initialized, in bus * reset, the packet's generation number doesn't match the current generation * number or the host reports a transmit error. * - * Return value: False (0) on failure, true (1) otherwise. + * Return value: 0 on success, negative errno on failure. */ int hpsb_send_packet(struct hpsb_packet *packet) { struct hpsb_host *host = packet->host; - if (host->is_shutdown || host->in_bus_reset - || (packet->generation != get_hpsb_generation(host))) { - return 0; - } + if (host->is_shutdown) + return -EINVAL; + if (host->in_bus_reset || + (packet->generation != get_hpsb_generation(host))) + return -EAGAIN; packet->state = hpsb_queued; @@ -532,23 +520,13 @@ int hpsb_send_packet(struct hpsb_packet data = kmalloc(packet->header_size + packet->data_size, GFP_ATOMIC); if (!data) { HPSB_ERR("unable to allocate memory for concatenating header and data"); - return 0; + return -ENOMEM; } memcpy(data, packet->header, packet->header_size); if (packet->data_size) - { - if (packet->data_be) { - memcpy(((u8*)data)+packet->header_size, packet->data, packet->data_size); - } else { - int i; - quadlet_t *my_data=(quadlet_t*) ((u8*) data + packet->data_size); - for (i=0; i < packet->data_size/4; i++) { - my_data[i] = cpu_to_be32(packet->data[i]); - } - } - } + memcpy(((u8*)data)+packet->header_size, packet->data, packet->data_size); dump_packet("send packet local:", packet->header, packet->header_size); @@ -558,7 +536,7 @@ int hpsb_send_packet(struct hpsb_packet kfree(data); - return 1; + return 0; } if (packet->type == hpsb_async && packet->node_id != ALL_NODES) { @@ -584,10 +562,33 @@ int hpsb_send_packet(struct hpsb_packet return host->driver->transmit_packet(host, packet); } +/* We could just use complete() directly as the packet complete + * callback, but this is more typesafe, in the sense that we get a + * compiler error if the prototype for complete() changes. */ + +static void complete_packet(void *data) +{ + complete((struct completion *) data); +} + +int hpsb_send_packet_and_wait(struct hpsb_packet *packet) +{ + struct completion done; + int retval; + + init_completion(&done); + hpsb_set_packet_complete_task(packet, complete_packet, &done); + retval = hpsb_send_packet(packet); + if (retval == 0) + wait_for_completion(&done); + + return retval; +} + static void send_packet_nocare(struct hpsb_packet *packet) { - if (!hpsb_send_packet(packet)) { - free_hpsb_packet(packet); + if (hpsb_send_packet(packet) < 0) { + hpsb_free_packet(packet); } } @@ -668,7 +669,6 @@ void handle_packet_response(struct hpsb_ } packet->state = hpsb_complete; - up(&packet->state_change); run_packet_complete(packet); } @@ -680,7 +680,7 @@ static struct hpsb_packet *create_reply_ dsize += (dsize % 4 ? 4 - (dsize % 4) : 0); - p = alloc_hpsb_packet(dsize); + p = hpsb_alloc_packet(dsize); if (p == NULL) { /* FIXME - send data_error response */ return NULL; @@ -820,6 +820,8 @@ static void handle_incoming_packet(struc if (rcode >= 0) { fill_async_readblock_resp(packet, rcode, length); send_packet_nocare(packet); + } else { + hpsb_free_packet(packet); } break; @@ -874,7 +876,7 @@ static void handle_incoming_packet(struc if (rcode >= 0) { send_packet_nocare(packet); } else { - free_hpsb_packet(packet); + hpsb_free_packet(packet); } break; } @@ -949,7 +951,6 @@ void abort_requests(struct hpsb_host *ho list_del(&packet->list); packet->state = hpsb_complete; packet->ack_code = ACKX_ABORTED; - up(&packet->state_change); run_packet_complete(packet); } } @@ -987,7 +988,6 @@ void abort_timedouts(unsigned long __opa list_del(&packet->list); packet->state = hpsb_complete; packet->ack_code = ACKX_TIMEOUT; - up(&packet->state_change); run_packet_complete(packet); } } @@ -1171,19 +1171,22 @@ static int ieee1394_dispatch_open(struct static int __init ieee1394_init(void) { - hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet), - 0, 0, NULL, NULL); - devfs_mk_dir("ieee1394"); - if (register_chrdev(IEEE1394_MAJOR, "ieee1394", &ieee1394_chardev_ops)) { HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR); - devfs_remove("ieee1394"); return -ENODEV; } + devfs_mk_dir("ieee1394"); + + hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet), + 0, 0, NULL, NULL); + + bus_register(&ieee1394_bus_type); + init_hpsb_highlevel(); init_csr(); + if (!disable_nodemgr) init_ieee1394_nodemgr(); else @@ -1198,6 +1201,9 @@ static void __exit ieee1394_cleanup(void cleanup_ieee1394_nodemgr(); cleanup_csr(); + + bus_unregister(&ieee1394_bus_type); + kmem_cache_destroy(hpsb_packet_cache); unregister_chrdev(IEEE1394_MAJOR, "ieee1394"); @@ -1213,16 +1219,15 @@ module_exit(ieee1394_cleanup); EXPORT_SYMBOL(hpsb_alloc_host); EXPORT_SYMBOL(hpsb_add_host); EXPORT_SYMBOL(hpsb_remove_host); -EXPORT_SYMBOL(hpsb_ref_host); -EXPORT_SYMBOL(hpsb_unref_host); /** ieee1394_core.c **/ EXPORT_SYMBOL(hpsb_speedto_str); EXPORT_SYMBOL(hpsb_set_packet_complete_task); -EXPORT_SYMBOL(alloc_hpsb_packet); -EXPORT_SYMBOL(free_hpsb_packet); +EXPORT_SYMBOL(hpsb_alloc_packet); +EXPORT_SYMBOL(hpsb_free_packet); EXPORT_SYMBOL(hpsb_send_phy_config); EXPORT_SYMBOL(hpsb_send_packet); +EXPORT_SYMBOL(hpsb_send_packet_and_wait); EXPORT_SYMBOL(hpsb_reset_bus); EXPORT_SYMBOL(hpsb_bus_reset); EXPORT_SYMBOL(hpsb_selfid_received); @@ -1282,6 +1287,7 @@ EXPORT_SYMBOL(hpsb_node_lock); EXPORT_SYMBOL(hpsb_register_protocol); EXPORT_SYMBOL(hpsb_unregister_protocol); EXPORT_SYMBOL(ieee1394_bus_type); +EXPORT_SYMBOL(nodemgr_for_each_host); /** csr.c **/ EXPORT_SYMBOL(hpsb_update_config_rom); diff -puN drivers/ieee1394/ieee1394_core.h~ieee1394-update drivers/ieee1394/ieee1394_core.h --- 25/drivers/ieee1394/ieee1394_core.h~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/ieee1394_core.h 2003-12-24 10:25:54.000000000 -0800 @@ -40,11 +40,6 @@ struct hpsb_packet { unsigned expect_response:1; unsigned no_waiter:1; - /* Data big endianness flag - may vary from request to request. The - * header is always in machine byte order. - * Not really used currently. */ - unsigned data_be:1; - /* Speed to transmit with: 0 = 100Mbps, 1 = 200Mbps, 2 = 400Mbps */ unsigned speed_code:2; @@ -64,9 +59,6 @@ struct hpsb_packet { struct hpsb_host *host; unsigned int generation; - /* Very core internal, don't care. */ - struct semaphore state_change; - /* Function (and possible data to pass to it) to call when this * packet is completed. */ void (*complete_routine)(void *); @@ -90,8 +82,8 @@ static inline struct hpsb_packet *driver void abort_timedouts(unsigned long __opaque); void abort_requests(struct hpsb_host *host); -struct hpsb_packet *alloc_hpsb_packet(size_t data_size); -void free_hpsb_packet(struct hpsb_packet *packet); +struct hpsb_packet *hpsb_alloc_packet(size_t data_size); +void hpsb_free_packet(struct hpsb_packet *packet); /* @@ -108,15 +100,23 @@ static inline unsigned int get_hpsb_gene } /* - * Send a PHY configuration packet. + * Send a PHY configuration packet, return 0 on success, negative + * errno on failure. */ int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt); /* - * Queue packet for transmitting, return 0 for failure. + * Queue packet for transmitting, return 0 on success, negative errno + * on failure. */ int hpsb_send_packet(struct hpsb_packet *packet); +/* + * Queue packet for transmitting, and block until the transaction + * completes. Return 0 on success, negative errno on failure. + */ +int hpsb_send_packet_and_wait(struct hpsb_packet *packet); + /* Initiate bus reset on the given host. Returns 1 if bus reset already in * progress, 0 otherwise. */ int hpsb_reset_bus(struct hpsb_host *host, int type); diff -puN drivers/ieee1394/ieee1394_transactions.c~ieee1394-update drivers/ieee1394/ieee1394_transactions.c --- 25/drivers/ieee1394/ieee1394_transactions.c~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/ieee1394_transactions.c 2003-12-24 10:25:54.000000000 -0800 @@ -263,7 +263,7 @@ struct hpsb_packet *hpsb_make_readpacket if (length == 0) return NULL; - packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0)); + packet = hpsb_alloc_packet(length + (length % 4 ? 4 - (length % 4) : 0)); if (!packet) return NULL; @@ -271,7 +271,7 @@ struct hpsb_packet *hpsb_make_readpacket packet->node_id = node; if (hpsb_get_tlabel(packet)) { - free_hpsb_packet(packet); + hpsb_free_packet(packet); return NULL; } @@ -291,7 +291,7 @@ struct hpsb_packet *hpsb_make_writepacke if (length == 0) return NULL; - packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0)); + packet = hpsb_alloc_packet(length + (length % 4 ? 4 - (length % 4) : 0)); if (!packet) return NULL; @@ -302,7 +302,7 @@ struct hpsb_packet *hpsb_make_writepacke packet->node_id = node; if (hpsb_get_tlabel(packet)) { - free_hpsb_packet(packet); + hpsb_free_packet(packet); return NULL; } @@ -325,7 +325,7 @@ struct hpsb_packet *hpsb_make_streampack if (length == 0) return NULL; - packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0)); + packet = hpsb_alloc_packet(length + (length % 4 ? 4 - (length % 4) : 0)); if (!packet) return NULL; @@ -335,7 +335,7 @@ struct hpsb_packet *hpsb_make_streampack packet->host = host; if (hpsb_get_tlabel(packet)) { - free_hpsb_packet(packet); + hpsb_free_packet(packet); return NULL; } @@ -353,13 +353,13 @@ struct hpsb_packet *hpsb_make_lockpacket struct hpsb_packet *p; u32 length; - p = alloc_hpsb_packet(8); + p = hpsb_alloc_packet(8); if (!p) return NULL; p->host = host; p->node_id = node; if (hpsb_get_tlabel(p)) { - free_hpsb_packet(p); + hpsb_free_packet(p); return NULL; } @@ -390,13 +390,13 @@ struct hpsb_packet *hpsb_make_lock64pack struct hpsb_packet *p; u32 length; - p = alloc_hpsb_packet(16); + p = hpsb_alloc_packet(16); if (!p) return NULL; p->host = host; p->node_id = node; if (hpsb_get_tlabel(p)) { - free_hpsb_packet(p); + hpsb_free_packet(p); return NULL; } @@ -429,7 +429,7 @@ struct hpsb_packet *hpsb_make_phypacket( { struct hpsb_packet *p; - p = alloc_hpsb_packet(0); + p = hpsb_alloc_packet(0); if (!p) return NULL; p->host = host; @@ -444,7 +444,7 @@ struct hpsb_packet *hpsb_make_isopacket( { struct hpsb_packet *p; - p = alloc_hpsb_packet(length); + p = hpsb_alloc_packet(length); if (!p) return NULL; p->host = host; @@ -478,13 +478,10 @@ int hpsb_read(struct hpsb_host *host, no } packet->generation = generation; - if (!hpsb_send_packet(packet)) { - retval = -EINVAL; + retval = hpsb_send_packet_and_wait(packet); + if (retval < 0) goto hpsb_read_fail; - } - down(&packet->state_change); - down(&packet->state_change); retval = hpsb_packet_success(packet); if (retval == 0) { @@ -497,7 +494,7 @@ int hpsb_read(struct hpsb_host *host, no hpsb_read_fail: hpsb_free_tlabel(packet); - free_hpsb_packet(packet); + hpsb_free_packet(packet); return retval; } @@ -520,18 +517,15 @@ int hpsb_write(struct hpsb_host *host, n return -ENOMEM; packet->generation = generation; - if (!hpsb_send_packet(packet)) { - retval = -EINVAL; + retval = hpsb_send_packet_and_wait(packet); + if (retval < 0) goto hpsb_write_fail; - } - down(&packet->state_change); - down(&packet->state_change); retval = hpsb_packet_success(packet); hpsb_write_fail: hpsb_free_tlabel(packet); - free_hpsb_packet(packet); + hpsb_free_packet(packet); return retval; } @@ -550,12 +544,10 @@ int hpsb_lock(struct hpsb_host *host, no return -ENOMEM; packet->generation = generation; - if (!hpsb_send_packet(packet)) { - retval = -EINVAL; + retval = hpsb_send_packet_and_wait(packet); + if (retval < 0) goto hpsb_lock_fail; - } - down(&packet->state_change); - down(&packet->state_change); + retval = hpsb_packet_success(packet); if (retval == 0) { @@ -564,7 +556,7 @@ int hpsb_lock(struct hpsb_host *host, no hpsb_lock_fail: hpsb_free_tlabel(packet); - free_hpsb_packet(packet); + hpsb_free_packet(packet); return retval; } @@ -582,12 +574,10 @@ int hpsb_lock64(struct hpsb_host *host, return -ENOMEM; packet->generation = generation; - if (!hpsb_send_packet(packet)) { - retval = -EINVAL; + retval = hpsb_send_packet_and_wait(packet); + if (retval < 0) goto hpsb_lock64_fail; - } - down(&packet->state_change); - down(&packet->state_change); + retval = hpsb_packet_success(packet); if (retval == 0) @@ -595,7 +585,7 @@ int hpsb_lock64(struct hpsb_host *host, hpsb_lock64_fail: hpsb_free_tlabel(packet); - free_hpsb_packet(packet); + hpsb_free_packet(packet); return retval; } @@ -626,10 +616,9 @@ int hpsb_send_gasp(struct hpsb_host *hos packet->no_waiter = 1; - if (!hpsb_send_packet(packet)) { - free_hpsb_packet(packet); - retval = -EINVAL; - } + retval = hpsb_send_packet(packet); + if (retval < 0) + hpsb_free_packet(packet); return retval; } diff -puN drivers/ieee1394/iso.c~ieee1394-update drivers/ieee1394/iso.c --- 25/drivers/ieee1394/iso.c~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/iso.c 2003-12-24 10:25:54.000000000 -0800 @@ -40,6 +40,7 @@ static struct hpsb_iso* hpsb_iso_common_ unsigned int data_buf_size, unsigned int buf_packets, int channel, + int dma_mode, int irq_interval, void (*callback)(struct hpsb_iso*)) { @@ -58,8 +59,13 @@ static struct hpsb_iso* hpsb_iso_common_ if (buf_packets < 2) buf_packets = 2; - if (irq_interval < 1 || irq_interval > buf_packets / 2) - irq_interval = 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 (irq_interval == 0) /* really interrupt for each packet*/ + irq_interval = 1; + else if ((irq_interval < 0) || (irq_interval > buf_packets / 4)) + irq_interval = buf_packets / 4; if (channel < -1 || channel >= 64) return NULL; @@ -83,6 +89,7 @@ static struct hpsb_iso* hpsb_iso_common_ init_waitqueue_head(&iso->waitq); iso->channel = channel; iso->irq_interval = irq_interval; + iso->dma_mode = dma_mode; dma_region_init(&iso->data_buf); iso->buf_size = round_up_to_page(data_buf_size); iso->buf_packets = buf_packets; @@ -136,7 +143,7 @@ struct hpsb_iso* hpsb_iso_xmit_init(stru { struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT, data_buf_size, buf_packets, - channel, irq_interval, callback); + channel, HPSB_ISO_DMA_DEFAULT, irq_interval, callback); if (!iso) return NULL; @@ -158,12 +165,13 @@ struct hpsb_iso* hpsb_iso_recv_init(stru unsigned int data_buf_size, unsigned int buf_packets, int channel, + int dma_mode, int irq_interval, void (*callback)(struct hpsb_iso*)) { struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV, data_buf_size, buf_packets, - channel, irq_interval, callback); + channel, dma_mode, irq_interval, callback); if (!iso) return NULL; diff -puN drivers/ieee1394/iso.h~ieee1394-update drivers/ieee1394/iso.h --- 25/drivers/ieee1394/iso.h~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/iso.h 2003-12-24 10:25:54.000000000 -0800 @@ -51,6 +51,14 @@ struct hpsb_iso_packet_info { enum hpsb_iso_type { HPSB_ISO_RECV = 0, HPSB_ISO_XMIT = 1 }; +/* The mode of the dma when receiving iso data. Must be supported by chip */ +enum raw1394_iso_dma_recv_mode { + HPSB_ISO_DMA_DEFAULT = -1, + HPSB_ISO_DMA_OLD_ABI = 0, + HPSB_ISO_DMA_BUFFERFILL = 1, + HPSB_ISO_DMA_PACKET_PER_BUFFER = 2 +}; + struct hpsb_iso { enum hpsb_iso_type type; @@ -68,6 +76,8 @@ struct hpsb_iso { int speed; /* IEEE1394_SPEED_100, 200, or 400 */ int channel; /* -1 if multichannel */ + int dma_mode; /* dma receive mode */ + /* greatest # of packets between interrupts - controls the maximum latency of the buffer */ @@ -139,6 +149,7 @@ struct hpsb_iso* hpsb_iso_recv_init(stru unsigned int data_buf_size, unsigned int buf_packets, int channel, + int dma_mode, int irq_interval, void (*callback)(struct hpsb_iso*)); diff -puN drivers/ieee1394/Kconfig~ieee1394-update drivers/ieee1394/Kconfig --- 25/drivers/ieee1394/Kconfig~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/Kconfig 2003-12-24 10:25:54.000000000 -0800 @@ -1,7 +1,7 @@ # -*- shell-script -*- menu "IEEE 1394 (FireWire) support (EXPERIMENTAL)" - depends on PCI && EXPERIMENTAL + depends on EXPERIMENTAL config IEEE1394 tristate "IEEE 1394 (FireWire) support (EXPERIMENTAL)" @@ -15,7 +15,7 @@ config IEEE1394 is the core support only, you will also need to select a driver for your IEEE 1394 adapter. - To compile this driver as a module, choose M here: the + To compile this driver as a module, say M here: the module will be called ieee1394. comment "Subsystem Options" @@ -56,13 +56,13 @@ comment "Texas Instruments PCILynx requi config IEEE1394_PCILYNX tristate "Texas Instruments PCILynx support" - depends on IEEE1394 && I2C_ALGOBIT + depends on PCI && IEEE1394 && I2C_ALGOBIT help Say Y here if you have an IEEE-1394 controller with the Texas Instruments PCILynx chip. Note: this driver is written for revision 2 of this chip and may not work with revision 0. - To compile this driver as a module, choose M here: the + To compile this driver as a module, say M here: the module will be called pcilynx. # Non-maintained pcilynx options @@ -72,7 +72,7 @@ config IEEE1394_PCILYNX # fi config IEEE1394_OHCI1394 tristate "OHCI-1394 support" - depends on IEEE1394 + depends on PCI && IEEE1394 help Enable this driver if you have an IEEE 1394 controller based on the OHCI-1394 specification. The current driver is only tested with OHCI @@ -80,7 +80,7 @@ config IEEE1394_OHCI1394 use one of these chipsets. It should work with any OHCI-1394 compliant card, however. - To compile this driver as a module, choose M here: the + To compile this driver as a module, say M here: the module will be called ohci1394. comment "Protocol Drivers" @@ -122,7 +122,7 @@ config IEEE1394_DV1394 The user-space API for dv1394 is documented in dv1394.h. - To compile this driver as a module, choose M here: the + To compile this driver as a module, say M here: the module will be called dv1394. config IEEE1394_RAWIO @@ -134,7 +134,7 @@ config IEEE1394_RAWIO direct communication of user programs with the IEEE 1394 bus and thus with the attached peripherals. - To compile this driver as a module, choose M here: the + To compile this driver as a module, say M here: the module will be called raw1394. config IEEE1394_CMP @@ -144,7 +144,7 @@ config IEEE1394_CMP This option enables the Connection Management Procedures (IEC61883-1) driver, which implements input and output plugs. - To compile this driver as a module, choose M here: the + To compile this driver as a module, say M here: the module will be called cmp. config IEEE1394_AMDTP @@ -157,7 +157,7 @@ config IEEE1394_AMDTP The userspace interface is documented in amdtp.h. - To compile this driver as a module, choose M here: the + To compile this driver as a module, say M here: the module will be called amdtp. endmenu diff -puN drivers/ieee1394/nodemgr.c~ieee1394-update drivers/ieee1394/nodemgr.c --- 25/drivers/ieee1394/nodemgr.c~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/nodemgr.c 2003-12-24 10:25:54.000000000 -0800 @@ -516,8 +516,7 @@ static struct device nodemgr_dev_templat .driver_data = &nodemgr_driverdata_ne, }; - -static struct device nodemgr_dev_template_host = { +struct device nodemgr_dev_template_host = { .bus = &ieee1394_bus_type, .release = nodemgr_release_host, .driver = &nodemgr_driver_host, @@ -1255,36 +1254,6 @@ void hpsb_unregister_protocol(struct hps } -/* Searches the list of ud's that match a ne as the parent. If the ud has - * a driver associated with it, we call that driver's update function - * with the ud as the argument. */ -static int nodemgr_driver_search_cb(struct device *dev, void *__data) -{ - struct node_entry *ne = __data; - struct unit_directory *ud; - - if (dev->driver_data == &nodemgr_driverdata_ne || - dev->driver_data == &nodemgr_driverdata_host) - return 0; - - ud = container_of(dev, struct unit_directory, device); - - if (&ne->device != ud->device.parent) - return 0; - - if (ud->device.driver) { - struct hpsb_protocol_driver *pdrv; - - pdrv = container_of(ud->device.driver, - struct hpsb_protocol_driver, driver); - - if (pdrv->update) - pdrv->update(ud); - } - - return 0; -} - /* * This function updates nodes that were present on the bus before the * reset and still are after the reset. The nodeid and the config rom @@ -1480,9 +1449,24 @@ static int nodemgr_probe_ne_cb(struct de ne->needs_probe = 0; return 1; } else { + struct list_head *lh; + /* Update unit_dirs with attached drivers */ - bus_for_each_dev(&ieee1394_bus_type, NULL, ne, - nodemgr_driver_search_cb); + list_for_each(lh, &dev->children) { + struct unit_directory *ud; + + ud = container_of(list_to_dev(lh), struct unit_directory, device); + + if (ud->device.driver) { + struct hpsb_protocol_driver *pdrv; + + pdrv = container_of(ud->device.driver, + struct hpsb_protocol_driver, driver); + + if (pdrv->update) + pdrv->update(ud); + } + } } return 0; } @@ -1664,7 +1648,6 @@ static int nodemgr_host_thread(void *__h allow_signal(SIGTERM); /* Setup our device-model entries */ - device_register(&host->device); nodemgr_create_host_dev_files(host); /* Sit and wait for a signal to probe the nodes on the bus. This @@ -1753,6 +1736,34 @@ struct node_entry *hpsb_nodeid_get_entry return ne; } +struct for_each_host_struct { + int (*cb)(struct hpsb_host *, void *); + void *data; +}; + +static int nodemgr_for_each_host_cb(struct device *dev, void *__data) +{ + struct for_each_host_struct *host_data = __data; + struct hpsb_host *host; + + if (dev->driver_data != &nodemgr_driverdata_host) + return 0; + + host = container_of(dev, struct hpsb_host, device); + + return host_data->cb(host, host_data->data); +} + +int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *)) +{ + struct for_each_host_struct host_data; + + host_data.cb = cb; + host_data.data = __data; + + return bus_for_each_dev(&ieee1394_bus_type, NULL, &host_data, nodemgr_for_each_host_cb); +} + /* The following four convenience functions use a struct node_entry * for addressing a node on the bus. They are intended for use by any * process context, not just the nodemgr thread, so we need to be a @@ -1821,11 +1832,6 @@ static void nodemgr_add_host(struct hpsb init_completion(&hi->exited); sema_init(&hi->reset_sem, 0); - memcpy(&host->device, &nodemgr_dev_template_host, - sizeof(host->device)); - host->device.parent = &host->pdev->dev; - snprintf(host->device.bus_id, BUS_ID_SIZE, "fw-host%d", host->id); - sprintf(hi->daemon_name, "knodemgrd_%d", host->id); hi->pid = kernel_thread(nodemgr_host_thread, hi, CLONE_KERNEL); @@ -1879,7 +1885,6 @@ static struct hpsb_highlevel nodemgr_hig void init_ieee1394_nodemgr(void) { - bus_register(&ieee1394_bus_type); driver_register(&nodemgr_driver_host); driver_register(&nodemgr_driver_ne); @@ -1892,5 +1897,4 @@ void cleanup_ieee1394_nodemgr(void) driver_unregister(&nodemgr_driver_ne); driver_unregister(&nodemgr_driver_host); - bus_unregister(&ieee1394_bus_type); } diff -puN drivers/ieee1394/nodemgr.h~ieee1394-update drivers/ieee1394/nodemgr.h --- 25/drivers/ieee1394/nodemgr.h~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/nodemgr.h 2003-12-24 10:25:54.000000000 -0800 @@ -219,7 +219,16 @@ int hpsb_node_lock(struct node_entry *ne int extcode, quadlet_t *data, quadlet_t arg); +/* Iterate the hosts, calling a given function with supplied data for each + * host. */ +int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *)); + + void init_ieee1394_nodemgr(void); void cleanup_ieee1394_nodemgr(void); + +/* The template for a host device */ +extern struct device nodemgr_dev_template_host; + #endif /* _IEEE1394_NODEMGR_H */ diff -puN drivers/ieee1394/ohci1394.c~ieee1394-update drivers/ieee1394/ohci1394.c --- 25/drivers/ieee1394/ohci1394.c~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/ohci1394.c 2003-12-24 10:25:54.000000000 -0800 @@ -134,7 +134,7 @@ #ifdef OHCI1394_DEBUG #define DBGMSG(card, fmt, args...) \ -printk(KERN_INFO "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) +printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) #else #define DBGMSG(card, fmt, args...) #endif @@ -158,10 +158,10 @@ printk(level "%s: " fmt "\n" , OHCI1394_ /* print card specific information */ #define PRINT(level, card, fmt, args...) \ -printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) +printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) static char version[] __devinitdata = - "$Rev: 1045 $ Ben Collins "; + "$Rev: 1087 $ Ben Collins "; /* Module Parameters */ static int phys_dma = 1; @@ -845,7 +845,7 @@ static int ohci_transmit(struct hpsb_hos PRINT(KERN_ERR, ohci->id, "Transmit packet size %Zd is too big", packet->data_size); - return 0; + return -EOVERFLOW; } /* Decide whether we have an iso, a request, or a response packet */ @@ -862,7 +862,7 @@ static int ohci_transmit(struct hpsb_hos if (in_interrupt()) { PRINT(KERN_ERR, ohci->id, "legacy IT context cannot be initialized during interrupt"); - return 0; + return -EINVAL; } if (alloc_dma_trm_ctx(ohci, &ohci->it_legacy_context, @@ -870,7 +870,7 @@ static int ohci_transmit(struct hpsb_hos OHCI1394_IsoXmitContextBase) < 0) { PRINT(KERN_ERR, ohci->id, "error initializing legacy IT context"); - return 0; + return -ENOMEM; } initialize_dma_trm_ctx(&ohci->it_legacy_context); @@ -890,7 +890,7 @@ static int ohci_transmit(struct hpsb_hos spin_unlock_irqrestore(&d->lock,flags); - return 1; + return 0; } static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) @@ -1113,8 +1113,8 @@ struct ohci_iso_recv { struct ohci1394_iso_tasklet task; int task_active; - enum { BUFFER_FILL_MODE, - PACKET_PER_BUFFER_MODE } dma_mode; + enum { BUFFER_FILL_MODE = 0, + PACKET_PER_BUFFER_MODE = 1 } dma_mode; /* memory and PCI mapping for the DMA descriptors */ struct dma_prog_region prog; @@ -1175,7 +1175,8 @@ static int ohci_iso_recv_init(struct hps /* use buffer-fill mode, unless irq_interval is 1 (note: multichannel requires buffer-fill) */ - if (iso->irq_interval == 1 && iso->channel != -1) { + if (((iso->irq_interval == 1 && iso->dma_mode == HPSB_ISO_DMA_OLD_ABI) || + iso->dma_mode == HPSB_ISO_DMA_PACKET_PER_BUFFER) && iso->channel != -1) { recv->dma_mode = PACKET_PER_BUFFER_MODE; } else { recv->dma_mode = BUFFER_FILL_MODE; @@ -1194,8 +1195,11 @@ static int ohci_iso_recv_init(struct hps } /* iso->irq_interval is in packets - translate that to blocks */ - /* (err, sort of... 1 is always the safest value) */ - recv->block_irq_interval = iso->irq_interval / recv->nblocks; + if (iso->irq_interval == 1) + recv->block_irq_interval = 1; + else + recv->block_irq_interval = iso->irq_interval * + ((recv->nblocks+1)/iso->buf_packets); if (recv->block_irq_interval*4 > recv->nblocks) recv->block_irq_interval = recv->nblocks/4; if (recv->block_irq_interval < 1) @@ -1205,6 +1209,10 @@ static int ohci_iso_recv_init(struct hps int max_packet_size; recv->nblocks = iso->buf_packets; + recv->block_irq_interval = iso->irq_interval; + if (recv->block_irq_interval * 4 > iso->buf_packets) + recv->block_irq_interval = iso->buf_packets / 4; + if (recv->block_irq_interval < 1) recv->block_irq_interval = 1; /* choose a buffer stride */ @@ -3271,7 +3279,6 @@ do { \ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - static unsigned int card_id_counter = 0; static int version_printed = 0; struct hpsb_host *host; @@ -3282,15 +3289,14 @@ static int __devinit ohci1394_pci_probe( PRINT_G(KERN_INFO, "%s", version); if (pci_enable_device(dev)) - FAIL(-ENXIO, "Failed to enable OHCI hardware %d", - card_id_counter++); + FAIL(-ENXIO, "Failed to enable OHCI hardware"); pci_set_master(dev); - host = hpsb_alloc_host(&ohci1394_driver, sizeof(struct ti_ohci)); + host = hpsb_alloc_host(&ohci1394_driver, sizeof(struct ti_ohci), &dev->dev); if (!host) FAIL(-ENOMEM, "Failed to allocate host structure"); ohci = host->hostdata; - ohci->id = card_id_counter++; + ohci->id = host->id; ohci->dev = dev; ohci->host = host; ohci->init_state = OHCI_INIT_ALLOC_HOST; @@ -3462,11 +3468,14 @@ static int __devinit ohci1394_pci_probe( static void ohci1394_pci_remove(struct pci_dev *pdev) { struct ti_ohci *ohci; + struct device *dev; ohci = pci_get_drvdata(pdev); if (!ohci) return; + dev = get_device(&ohci->host->device); + switch (ohci->init_state) { case OHCI_INIT_DONE: hpsb_remove_host(ohci->host); @@ -3489,7 +3498,7 @@ static void ohci1394_pci_remove(struct p /* Disable IRM Contender */ set_phy_reg(ohci, 4, ~0xc0 & get_phy_reg(ohci, 4)); - + /* Clear link control register */ reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff); @@ -3521,7 +3530,7 @@ static void ohci1394_pci_remove(struct p ohci->selfid_buf_cpu, ohci->selfid_buf_bus); OHCI_DMA_FREE("consistent selfid_buf"); - + case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER: pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, ohci->csr_config_rom_cpu, @@ -3555,8 +3564,10 @@ static void ohci1394_pci_remove(struct p case OHCI_INIT_ALLOC_HOST: pci_set_drvdata(ohci->dev, NULL); - hpsb_unref_host(ohci->host); } + + if (dev) + put_device(dev); } diff -puN drivers/ieee1394/oui.db~ieee1394-update drivers/ieee1394/oui.db --- 25/drivers/ieee1394/oui.db~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/oui.db 2003-12-24 10:25:54.000000000 -0800 @@ -1612,7 +1612,7 @@ 000658 Helmut Fischer GmbH & Co. KG 000659 EAL (Apeldoorn) B.V. 00065A Strix Systems -00065B Dell Inc. +00065B Dell Computer Corp. 00065C Malachite Technologies, Inc. 00065D Heidelberg Web Systems 00065E Photuris, Inc. @@ -3965,7 +3965,7 @@ 00B0C2 Cisco Systems, Inc. 00B0C7 Tellabs Operations, Inc. 00B0CE TECHNOLOGY RESCUE -00B0D0 Dell Inc. +00B0D0 Dell Computer Corp. 00B0DB Nextcell, Inc. 00B0DF Reliable Data Technology, Inc. 00B0E7 British Federal Ltd. @@ -4054,7 +4054,7 @@ 00C04C DEPARTMENT OF FOREIGN AFFAIRS 00C04D MITEC, INC. 00C04E COMTROL CORPORATION -00C04F Dell Inc. +00C04F DELL COMPUTER CORPORATION 00C050 TOYO DENKI SEIZO K.K. 00C051 ADVANCED INTEGRATION RESEARCH 00C052 BURR-BROWN diff -puN drivers/ieee1394/pcilynx.c~ieee1394-update drivers/ieee1394/pcilynx.c --- 25/drivers/ieee1394/pcilynx.c~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/pcilynx.c 2003-12-24 10:25:54.000000000 -0800 @@ -521,10 +521,6 @@ static void send_next(struct ti_lynx *ly break; } - if (!packet->data_be) { - pcl.buffer[1].control |= PCL_BIGENDIAN; - } - put_pcl(lynx, d->pcl, &pcl); run_pcl(lynx, d->pcl_start, d->channel); } @@ -540,7 +536,7 @@ static int lynx_transmit(struct hpsb_hos if (packet->data_size >= 4096) { PRINT(KERN_ERR, lynx->id, "transmit packet data too big (%Zd)", packet->data_size); - return 0; + return -EOVERFLOW; } switch (packet->type) { @@ -554,7 +550,7 @@ static int lynx_transmit(struct hpsb_hos default: PRINT(KERN_ERR, lynx->id, "invalid packet type %d", packet->type); - return 0; + return -EINVAL; } if (packet->tcode == TCODE_WRITEQ @@ -570,7 +566,7 @@ static int lynx_transmit(struct hpsb_hos spin_unlock_irqrestore(&d->queue_lock, flags); - return 1; + return 0; } @@ -1120,7 +1116,7 @@ static ssize_t mem_read(struct file *fil retval = copy_to_user(buffer, md->lynx->mem_dma_buffer, count); up(&md->lynx->mem_dma_mutex); - if (retval < 0) return retval; + if (retval) return -EFAULT; *offset += count; return count; } @@ -1141,14 +1137,17 @@ static ssize_t mem_write(struct file *fi /* FIXME: dereferencing pointers to PCI mem doesn't work everywhere */ switch (md->type) { case aux: - copy_from_user(md->lynx->aux_port+(*offset), buffer, count); + if (copy_from_user(md->lynx->aux_port+(*offset), buffer, count)) + return -EFAULT; break; case ram: - copy_from_user(md->lynx->local_ram+(*offset), buffer, count); + if (copy_from_user(md->lynx->local_ram+(*offset), buffer, count)) + return -EFAULT; break; case rom: /* the ROM may be writeable */ - copy_from_user(md->lynx->local_rom+(*offset), buffer, count); + if (copy_from_user(md->lynx->local_rom+(*offset), buffer, count)) + return -EFAULT; break; } @@ -1443,12 +1442,15 @@ static void iso_rcv_bh(struct ti_lynx *l static void remove_card(struct pci_dev *dev) { struct ti_lynx *lynx; + struct device *lynx_dev; int i; lynx = pci_get_drvdata(dev); if (!lynx) return; pci_set_drvdata(dev, NULL); + lynx_dev = get_device(&lynx->host->device); + switch (lynx->state) { case is_host: reg_write(lynx, PCI_INT_ENABLE, 0); @@ -1498,7 +1500,9 @@ static void remove_card(struct pci_dev * } tasklet_kill(&lynx->iso_rcv.tq); - hpsb_unref_host(lynx->host); + + if (lynx_dev) + put_device(lynx_dev); } @@ -1535,7 +1539,7 @@ static int __devinit add_card(struct pci error = -ENOMEM; - host = hpsb_alloc_host(&lynx_driver, sizeof(struct ti_lynx)); + host = hpsb_alloc_host(&lynx_driver, sizeof(struct ti_lynx), &dev->dev); if (!host) FAIL("failed to allocate control structure memory"); lynx = host->hostdata; diff -puN drivers/ieee1394/raw1394.c~ieee1394-update drivers/ieee1394/raw1394.c --- 25/drivers/ieee1394/raw1394.c~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/raw1394.c 2003-12-24 10:25:54.000000000 -0800 @@ -128,7 +128,7 @@ static void free_pending_request(struct } else if (req->free_data) { kfree(req->data); } - free_hpsb_packet(req->packet); + hpsb_free_packet(req->packet); kfree(req); } @@ -558,7 +558,7 @@ static int state_initialized(struct file lh = lh->next; } hi = list_entry(lh, struct host_info, list); - hpsb_ref_host(hi->host); // XXX Need to handle failure case + get_device(&hi->host->device); // XXX Need to handle failure case list_add_tail(&fi->list, &hi->file_info_list); fi->host = hi->host; fi->state = connected; @@ -782,7 +782,7 @@ static int handle_async_request(struct f packet->generation = req->req.generation; - if (!hpsb_send_packet(packet)) { + if (hpsb_send_packet(packet) < 0) { req->req.error = RAW1394_ERROR_SEND_ERROR; req->req.length = 0; hpsb_free_tlabel(packet); @@ -823,7 +823,7 @@ static int handle_iso_send(struct file_i /* Update the generation of the packet just before sending. */ packet->generation = req->req.generation; - if (!hpsb_send_packet(packet)) { + if (hpsb_send_packet(packet) < 0) { req->req.error = RAW1394_ERROR_SEND_ERROR; queue_complete_req(req); } @@ -846,7 +846,7 @@ static int handle_async_send(struct file return sizeof(struct raw1394_request); } - packet = alloc_hpsb_packet(req->req.length-header_length); + packet = hpsb_alloc_packet(req->req.length-header_length); req->packet = packet; if (!packet) return -ENOMEM; @@ -885,7 +885,7 @@ static int handle_async_send(struct file /* Update the generation of the packet just before sending. */ packet->generation = req->req.generation; - if (!hpsb_send_packet(packet)) { + if (hpsb_send_packet(packet) < 0) { req->req.error = RAW1394_ERROR_SEND_ERROR; queue_complete_req(req); } @@ -1797,6 +1797,106 @@ static int arm_unregister(struct file_in return sizeof(struct raw1394_request); } +/* Copy data from ARM buffer(s) to user buffer. */ +static int arm_get_buf(struct file_info *fi, struct pending_request *req) +{ + struct arm_addr *arm_addr = NULL; + unsigned long flags; + unsigned long offset; + + struct list_head *entry; + + DBGMSG("arm_get_buf " + "addr(Offset): %04X %08X length: %u", + (u32) ((req->req.address >> 32) & 0xFFFF), + (u32) (req->req.address & 0xFFFFFFFF), + (u32) req->req.length); + + spin_lock_irqsave(&host_info_lock, flags); + entry = fi->addr_list.next; + while (entry != &(fi->addr_list)) { + arm_addr = list_entry(entry, struct arm_addr, addr_list); + if ((arm_addr->start <= req->req.address) && + (arm_addr->end > req->req.address)) { + if (req->req.address + req->req.length <= arm_addr->end) { + offset = req->req.address - arm_addr->start; + + DBGMSG("arm_get_buf copy_to_user( %08X, %08X, %u )", + (u32) req->req.recvb, + (u32) (arm_addr->addr_space_buffer+offset), + (u32) req->req.length); + + if (copy_to_user(int2ptr(req->req.recvb), arm_addr->addr_space_buffer+offset, req->req.length)) { + spin_unlock_irqrestore(&host_info_lock, flags); + return (-EFAULT); + } + + spin_unlock_irqrestore(&host_info_lock, flags); + free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ + return sizeof(struct raw1394_request); + } else { + DBGMSG("arm_get_buf request exceeded mapping"); + spin_unlock_irqrestore(&host_info_lock, flags); + return (-EINVAL); + } + } + entry = entry->next; + } + spin_unlock_irqrestore(&host_info_lock, flags); + return (-EINVAL); +} + + +/* Copy data from user buffer to ARM buffer(s). */ +static int arm_set_buf(struct file_info *fi, struct pending_request *req) +{ + struct arm_addr *arm_addr = NULL; + unsigned long flags; + unsigned long offset; + + struct list_head *entry; + + DBGMSG("arm_set_buf " + "addr(Offset): %04X %08X length: %u", + (u32) ((req->req.address >> 32) & 0xFFFF), + (u32) (req->req.address & 0xFFFFFFFF), + (u32) req->req.length); + + + spin_lock_irqsave(&host_info_lock, flags); + entry = fi->addr_list.next; + while (entry != &(fi->addr_list)) { + arm_addr = list_entry(entry, struct arm_addr, addr_list); + if ((arm_addr->start <= req->req.address) && + (arm_addr->end > req->req.address)) { + if (req->req.address + req->req.length <= arm_addr->end) { + offset = req->req.address - arm_addr->start; + + DBGMSG("arm_set_buf copy_from_user( %08X, %08X, %u )", + (u32) (arm_addr->addr_space_buffer+offset), + (u32) req->req.sendb, + (u32) req->req.length); + + if (copy_from_user(arm_addr->addr_space_buffer+offset, int2ptr(req->req.sendb), req->req.length)) { + spin_unlock_irqrestore(&host_info_lock, flags); + return (-EFAULT); + } + + spin_unlock_irqrestore(&host_info_lock, flags); + free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ + return sizeof(struct raw1394_request); + } else { + DBGMSG("arm_set_buf request exceeded mapping"); + spin_unlock_irqrestore(&host_info_lock, flags); + return (-EINVAL); + } + } + entry = entry->next; + } + spin_unlock_irqrestore(&host_info_lock, flags); + return (-EINVAL); +} + static int reset_notification(struct file_info *fi, struct pending_request *req) { DBGMSG("reset_notification called - switch %s ", @@ -1829,9 +1929,8 @@ static int write_phypacket(struct file_i spin_unlock_irq(&fi->reqlists_lock); packet->generation = req->req.generation; retval = hpsb_send_packet(packet); - DBGMSG("write_phypacket send_packet called => retval: %d ", - retval); - if (! retval) { + DBGMSG("write_phypacket send_packet called => retval: %d ", retval); + if (retval < 0) { req->req.error = RAW1394_ERROR_SEND_ERROR; req->req.length = 0; queue_complete_req(req); @@ -1912,6 +2011,12 @@ static int state_connected(struct file_i case RAW1394_REQ_ARM_UNREGISTER: return arm_unregister(fi, req); + case RAW1394_REQ_ARM_SET_BUF: + return arm_set_buf(fi, req); + + case RAW1394_REQ_ARM_GET_BUF: + return arm_get_buf(fi, req); + case RAW1394_REQ_RESET_NOTIFY: return reset_notification(fi, req); @@ -2137,6 +2242,7 @@ static int raw1394_iso_recv_init(struct stat.config.data_buf_size, stat.config.buf_packets, stat.config.channel, + stat.config.dma_mode, stat.config.irq_interval, rawiso_activity_cb); if (!fi->iso_handle) @@ -2489,7 +2595,7 @@ static int raw1394_release(struct inode list_del(&fi->list); spin_unlock_irq(&host_info_lock); - hpsb_unref_host(fi->host); + put_device(&fi->host->device); } kfree(fi); diff -puN drivers/ieee1394/raw1394.h~ieee1394-update drivers/ieee1394/raw1394.h --- 25/drivers/ieee1394/raw1394.h~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/raw1394.h 2003-12-24 10:25:54.000000000 -0800 @@ -30,6 +30,8 @@ #define RAW1394_REQ_ARM_REGISTER 300 #define RAW1394_REQ_ARM_UNREGISTER 301 +#define RAW1394_REQ_ARM_SET_BUF 302 +#define RAW1394_REQ_ARM_GET_BUF 303 #define RAW1394_REQ_RESET_NOTIFY 400 @@ -149,6 +151,9 @@ struct raw1394_iso_config { /* xmit only - iso transmission speed */ __u8 speed; + /* The mode of the dma when receiving iso data. Must be supported by chip */ + __u8 dma_mode; + /* max. latency of buffer, in packets (-1 if you don't care) */ __s32 irq_interval; }; diff -puN drivers/ieee1394/sbp2.c~ieee1394-update drivers/ieee1394/sbp2.c --- 25/drivers/ieee1394/sbp2.c~ieee1394-update 2003-12-24 10:25:54.000000000 -0800 +++ 25-akpm/drivers/ieee1394/sbp2.c 2003-12-24 10:25:54.000000000 -0800 @@ -77,7 +77,7 @@ #include "sbp2.h" static char version[] __devinitdata = - "$Rev: 1034 $ Ben Collins "; + "$Rev: 1082 $ Ben Collins "; /* * Module load parameter definitions @@ -361,38 +361,34 @@ static int sbp2util_down_timeout(atomic_ static void sbp2_free_packet(struct hpsb_packet *packet) { hpsb_free_tlabel(packet); - free_hpsb_packet(packet); + hpsb_free_packet(packet); } -/* - * This function is called to retrieve a block write packet from our - * packet pool. This function is used in place of calling - * alloc_hpsb_packet (which costs us three kmallocs). Instead we just pull - * out a free request packet and re-initialize values in it. I'm sure this - * can still stand some more optimization. +/* This is much like hpsb_node_write(), except it ignores the response + * subaction and returns immediately. Can be used from interrupts. */ -static struct hpsb_packet * -sbp2util_allocate_write_packet(struct sbp2scsi_host_info *hi, - struct node_entry *ne, u64 addr, - size_t data_size, - quadlet_t *data) +int sbp2util_node_write_no_wait(struct node_entry *ne, u64 addr, + quadlet_t *buffer, size_t length) { struct hpsb_packet *packet; - packet = hpsb_make_writepacket(hi->host, ne->nodeid, - addr, data, data_size); - + packet = hpsb_make_writepacket(ne->host, ne->nodeid, + addr, buffer, length); if (!packet) - return NULL; + return -ENOMEM; hpsb_set_packet_complete_task(packet, (void (*)(void*))sbp2_free_packet, packet); hpsb_node_fill_packet(ne, packet); - return packet; -} + if (hpsb_send_packet(packet) < 0) { + sbp2_free_packet(packet); + return -EIO; + } + return 0; +} /* * This function is called to create a pool of command orbs used for @@ -1734,35 +1730,26 @@ static int sbp2_max_speed_and_size(struc */ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait) { - struct sbp2scsi_host_info *hi = scsi_id->hi; - struct hpsb_packet *packet; quadlet_t data; - + u64 addr; + int retval; + SBP2_DEBUG("sbp2_agent_reset"); /* * Ok, let's write to the target's management agent register */ data = ntohl(SBP2_AGENT_RESET_DATA); - packet = sbp2util_allocate_write_packet(hi, scsi_id->ne, - scsi_id->sbp2_command_block_agent_addr + - SBP2_AGENT_RESET_OFFSET, - 4, &data); - - if (!packet) { - SBP2_ERR("sbp2util_allocate_write_packet failed"); - return(-ENOMEM); - } + addr = scsi_id->sbp2_command_block_agent_addr + SBP2_AGENT_RESET_OFFSET; - if (!hpsb_send_packet(packet)) { - SBP2_ERR("hpsb_send_packet failed"); - sbp2_free_packet(packet); - return(-EIO); - } + if (wait) + retval = hpsb_node_write(scsi_id->ne, addr, &data, 4); + else + retval = sbp2util_node_write_no_wait(scsi_id->ne, addr, &data, 4); - if (wait) { - down(&packet->state_change); - down(&packet->state_change); + if (retval < 0) { + SBP2_ERR("hpsb_node_write failed.\n"); + return -EIO; } /* @@ -2032,8 +2019,9 @@ static int sbp2_link_orb_command(struct struct sbp2_command_info *command) { struct sbp2scsi_host_info *hi = scsi_id->hi; - struct hpsb_packet *packet; struct sbp2_command_orb *command_orb = &command->command_orb; + struct node_entry *ne = scsi_id->ne; + u64 addr; outstanding_orb_incr; SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x", @@ -2049,40 +2037,30 @@ static int sbp2_link_orb_command(struct * Check to see if there are any previous orbs to use */ if (scsi_id->last_orb == NULL) { - + quadlet_t data[2]; + /* * Ok, let's write to the target's management agent register */ - if (hpsb_node_entry_valid(scsi_id->ne)) { - - packet = sbp2util_allocate_write_packet(hi, scsi_id->ne, - scsi_id->sbp2_command_block_agent_addr + - SBP2_ORB_POINTER_OFFSET, 8, NULL); - - if (!packet) { - SBP2_ERR("sbp2util_allocate_write_packet failed"); - return(-ENOMEM); - } - - packet->data[0] = ORB_SET_NODE_ID(hi->host->node_id); - packet->data[1] = command->command_orb_dma; - sbp2util_cpu_to_be32_buffer(packet->data, 8); - - SBP2_ORB_DEBUG("write command agent, command orb %p", command_orb); + addr = scsi_id->sbp2_command_block_agent_addr + SBP2_ORB_POINTER_OFFSET; + data[0] = ORB_SET_NODE_ID(hi->host->node_id); + data[1] = command->command_orb_dma; + sbp2util_cpu_to_be32_buffer(data, 8); - if (!hpsb_send_packet(packet)) { - SBP2_ERR("hpsb_send_packet failed"); - sbp2_free_packet(packet); - return(-EIO); - } + SBP2_ORB_DEBUG("write command agent, command orb %p", command_orb); - SBP2_ORB_DEBUG("write command agent complete"); + if (sbp2util_node_write_no_wait(ne, addr, data, 8) < 0) { + SBP2_ERR("sbp2util_node_write_no_wait failed.\n"); + return -EIO; } + SBP2_ORB_DEBUG("write command agent complete"); + scsi_id->last_orb = command_orb; scsi_id->last_orb_dma = command->command_orb_dma; } else { + quadlet_t data; /* * We have an orb already sent (maybe or maybe not @@ -2102,25 +2080,14 @@ static int sbp2_link_orb_command(struct /* * Ring the doorbell */ - if (hpsb_node_entry_valid(scsi_id->ne)) { - quadlet_t data = cpu_to_be32(command->command_orb_dma); + data = cpu_to_be32(command->command_orb_dma); + addr = scsi_id->sbp2_command_block_agent_addr + SBP2_DOORBELL_OFFSET; - packet = sbp2util_allocate_write_packet(hi, scsi_id->ne, - scsi_id->sbp2_command_block_agent_addr + - SBP2_DOORBELL_OFFSET, 4, &data); - - if (!packet) { - SBP2_ERR("sbp2util_allocate_write_packet failed"); - return(-ENOMEM); - } + SBP2_ORB_DEBUG("ring doorbell, command orb %p", command_orb); - SBP2_ORB_DEBUG("ring doorbell, command orb %p", command_orb); - - if (!hpsb_send_packet(packet)) { - SBP2_ERR("hpsb_send_packet failed"); - sbp2_free_packet(packet); - return(-EIO); - } + if (sbp2util_node_write_no_wait(ne, addr, &data, 4) < 0) { + SBP2_ERR("sbp2util_node_write_no_wait failed"); + return(-EIO); } scsi_id->last_orb = command_orb; _