Thread: [Linux1394-cvslog] rev 612 - trunk
Brought to you by:
aeb,
bencollins
From: SVN U. <ben...@li...> - 2002-10-14 12:43:27
|
Author: bencollins Date: 2002-10-14 08:43:23 -0400 (Mon, 14 Oct 2002) New Revision: 612 Modified: trunk/hosts.c trunk/hosts.h trunk/ieee1394_core.c trunk/ieee1394_core.h trunk/ieee1394_transactions.c trunk/ieee1394_transactions.h trunk/ieee1394_types.h trunk/nodemgr.c trunk/nodemgr.h trunk/raw1394.c trunk/sbp2.c Log: Say hello to per-node transaction label management. Modified: trunk/ieee1394_core.c ============================================================================== --- trunk/ieee1394_core.c (original) +++ trunk/ieee1394_core.c 2002-10-14 08:43:25.000000000 -0400 @@ -1165,8 +1165,8 @@ EXPORT_SYMBOL(hpsb_packet_sent); EXPORT_SYMBOL(hpsb_packet_received); -EXPORT_SYMBOL(get_tlabel); -EXPORT_SYMBOL(free_tlabel); +EXPORT_SYMBOL(hpsb_get_tlabel); +EXPORT_SYMBOL(hpsb_free_tlabel); EXPORT_SYMBOL(fill_async_readquad); EXPORT_SYMBOL(fill_async_readquad_resp); EXPORT_SYMBOL(fill_async_readblock); @@ -1207,6 +1207,7 @@ EXPORT_SYMBOL(hpsb_guid_get_entry); EXPORT_SYMBOL(hpsb_nodeid_get_entry); +EXPORT_SYMBOL(hpsb_check_nodeid); EXPORT_SYMBOL(hpsb_node_fill_packet); EXPORT_SYMBOL(hpsb_node_read); EXPORT_SYMBOL(hpsb_node_write); Modified: trunk/ieee1394_core.h ============================================================================== --- trunk/ieee1394_core.h (original) +++ trunk/ieee1394_core.h 2002-10-14 08:43:25.000000000 -0400 @@ -38,6 +38,9 @@ char ack_code; char tcode; + /* A pointer to the tlabel pool we used for our tlabel */ + struct hpsb_tlabel_pool *tpool; + unsigned expect_response:1; unsigned no_waiter:1; Modified: trunk/raw1394.c ============================================================================== --- trunk/raw1394.c (original) +++ trunk/raw1394.c 2002-10-14 08:43:25.000000000 -0400 @@ -171,7 +171,7 @@ } if (req->req.type != RAW1394_REQ_PHYPACKET) - free_tlabel(packet->host, packet->node_id, packet->tlabel); + hpsb_free_tlabel(packet); queue_complete_req(req); } @@ -762,7 +762,7 @@ if (!hpsb_send_packet(packet)) { req->req.error = RAW1394_ERROR_SEND_ERROR; req->req.length = 0; - free_tlabel(packet->host, packet->node_id, packet->tlabel); + hpsb_free_tlabel(packet); queue_complete_req(req); } return sizeof(struct raw1394_request); Modified: trunk/ieee1394_transactions.c ============================================================================== --- trunk/ieee1394_transactions.c (original) +++ trunk/ieee1394_transactions.c 2002-10-14 08:43:25.000000000 -0400 @@ -12,12 +12,14 @@ #include <linux/sched.h> #include <asm/errno.h> #include <asm/bitops.h> +#include <linux/interrupt.h> #include "ieee1394.h" #include "ieee1394_types.h" #include "hosts.h" #include "ieee1394_core.h" #include "highlevel.h" +#include "nodemgr.h" #define PREP_ASYNC_HEAD_ADDRESS(tc) \ @@ -148,9 +150,8 @@ /** - * get_tlabel - allocate a transaction label - * @host: host to be used for transmission - * @nodeid: the node ID of the transmission target + * hpsb_get_tlabel - allocate a transaction label + * @packet: the packet who's tlabel/tpool we set * @wait: whether to sleep if no tlabel is available * * Every asynchronous transaction on the 1394 bus needs a transaction label to @@ -159,72 +160,71 @@ * matching possible without ambiguity. * * There are 64 different tlabels, so an allocated tlabel has to be freed with - * free_tlabel() after the transaction is complete (unless it's reused again for + * hpsb_free_tlabel() after the transaction is complete (unless it's reused again for * the same target node). * - * @wait must not be set to true if you are calling from interrupt context. + * @wait is ignored if in_interrupt() * - * Return value: The allocated transaction label or -1 if there was no free - * tlabel and @wait is false. + * Return value: Zero on success, otherwise non-zero. A non-zero return + * generally means there are no available tlabels. */ -int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait) +int hpsb_get_tlabel(struct hpsb_packet *packet, int wait) { - int tlabel = 0; unsigned long flags; - int found_tlabel = 0; + struct hpsb_tlabel_pool *tp; + struct node_entry *ne = hpsb_check_nodeid(packet->node_id); - if (wait) { - down(&host->tlabel_count); - } else { - if (down_trylock(&host->tlabel_count)) return -1; - } + BUG_ON(packet->tpool != NULL); - spin_lock_irqsave(&host->tlabel_lock, flags); + if (!ne) + tp = &packet->host->tpool; + else + tp = &ne->tpool; - while (!found_tlabel) { - tlabel = host->tlabel_current; - if (tlabel < 32 && !(host->tlabel_pool[0] & 1 << tlabel)) { - host->tlabel_pool[0] |= 1 << tlabel; - found_tlabel = 1; - } else if (!(host->tlabel_pool[1] & 1 << (tlabel - 32))) { - host->tlabel_pool[1] |= 1 << (tlabel - 32); - found_tlabel = 1; - } - host->tlabel_current = (host->tlabel_current + 1) % 64; + if (wait && !in_interrupt()) { + down(&tp->count); + } else { + if (down_trylock(&tp->count)) + return 1; } + + spin_lock_irqsave(&tp->lock, flags); - spin_unlock_irqrestore(&host->tlabel_lock, flags); + packet->tlabel = find_next_zero_bit(&tp->pool, 64, tp->next); + tp->next = (packet->tlabel + 1) % 64; + set_bit(packet->tlabel, &tp->pool); + packet->tpool = tp; + + spin_unlock_irqrestore(&tp->lock, flags); - return tlabel; + return 0; } -/** - * free_tlabel - free an allocated transaction label - * @host: host to be used for transmission - * @nodeid: the node ID of the transmission target - * @tlabel: the transaction label to free +/** + * hpsb_free_tlabel - free an allocated transaction label + * @packet: packet whos tlabel/tpool needs to be cleared * - * Frees the transaction label allocated with get_tlabel(). The tlabel has to - * be freed after the transaction is complete (i.e. response was received for a - * split transaction or packet was sent for a unified transaction). + * Frees the transaction label allocated with hpsb_get_tlabel(). The + * tlabel has to be freed after the transaction is complete (i.e. response + * was received for a split transaction or packet was sent for a unified + * transaction). * * A tlabel must not be freed twice. */ -void free_tlabel(struct hpsb_host *host, nodeid_t nodeid, int tlabel) +void hpsb_free_tlabel(struct hpsb_packet *packet) { unsigned long flags; + struct hpsb_tlabel_pool *tp = packet->tpool; - spin_lock_irqsave(&host->tlabel_lock, flags); - - if (tlabel < 32) { - host->tlabel_pool[0] &= ~(1 << tlabel); - } else { - host->tlabel_pool[1] &= ~(1 << (tlabel-32)); - } + BUG_ON(packet->tlabel > 63 || packet->tlabel < 0); + BUG_ON(tp == NULL); - spin_unlock_irqrestore(&host->tlabel_lock, flags); + spin_lock_irqsave(&tp->lock, flags); + packet->tpool = NULL; + clear_bit(packet->tlabel, &tp->pool); + spin_unlock_irqrestore(&tp->lock, flags); - up(&host->tlabel_count); + up(&tp->count); } @@ -306,8 +306,11 @@ if (!p) return NULL; p->host = host; - p->tlabel = get_tlabel(host, node, 1); p->node_id = node; + if (hpsb_get_tlabel(p, 1)) { + free_hpsb_packet(p); + return NULL; + } fill_async_readquad(p, addr); return p; @@ -322,8 +325,11 @@ if (!p) return NULL; p->host = host; - p->tlabel = get_tlabel(host, node, 1); p->node_id = node; + if (hpsb_get_tlabel(p, 1)) { + free_hpsb_packet(p); + return NULL; + } fill_async_readblock(p, addr, length); return p; @@ -339,8 +345,11 @@ if (!p) return NULL; p->host = host; - p->tlabel = get_tlabel(host, node, 1); p->node_id = node; + if (hpsb_get_tlabel(p, 1)) { + free_hpsb_packet(p); + return NULL; + } fill_async_writequad(p, addr, data); return p; @@ -360,8 +369,11 @@ } p->host = host; - p->tlabel = get_tlabel(host, node, 1); p->node_id = node; + if (hpsb_get_tlabel(p, 1)) { + free_hpsb_packet(p); + return NULL; + } fill_async_writeblock(p, addr, length); return p; @@ -376,8 +388,11 @@ if (!p) return NULL; p->host = host; - p->tlabel = get_tlabel(host, node, 1); p->node_id = node; + if (hpsb_get_tlabel(p, 1)) { + free_hpsb_packet(p); + return NULL; + } switch (extcode) { case EXTCODE_FETCH_ADD: @@ -401,8 +416,11 @@ if (!p) return NULL; p->host = host; - p->tlabel = get_tlabel(host, node, 1); p->node_id = node; + if (hpsb_get_tlabel(p, 1)) { + free_hpsb_packet(p); + return NULL; + } switch (extcode) { case EXTCODE_FETCH_ADD: @@ -475,7 +493,7 @@ } hpsb_read_fail: - free_tlabel(host, node, packet->tlabel); + hpsb_free_tlabel(packet); free_hpsb_packet(packet); return retval; @@ -530,7 +548,7 @@ retval = hpsb_packet_success(packet); hpsb_write_fail: - free_tlabel(host, node, packet->tlabel); + hpsb_free_tlabel(packet); free_hpsb_packet(packet); return retval; @@ -550,8 +568,11 @@ } packet->host = host; - packet->tlabel = get_tlabel(host, node, 1); packet->node_id = node; + if (hpsb_get_tlabel(packet, 1)) { + free_hpsb_packet(packet); + return -ENOMEM; + } switch (extcode) { case EXTCODE_MASK_SWAP: @@ -586,7 +607,7 @@ } hpsb_lock_fail: - free_tlabel(host, node, packet->tlabel); + hpsb_free_tlabel(packet); free_hpsb_packet(packet); return retval; Modified: trunk/ieee1394_transactions.h ============================================================================== --- trunk/ieee1394_transactions.h (original) +++ trunk/ieee1394_transactions.h 2002-10-14 08:43:25.000000000 -0400 @@ -27,8 +27,8 @@ /* * Get and free transaction labels. */ -int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait); -void free_tlabel(struct hpsb_host *host, nodeid_t nodeid, int tlabel); +int hpsb_get_tlabel(struct hpsb_packet *packet, int wait); +void hpsb_free_tlabel(struct hpsb_packet *packet); struct hpsb_packet *hpsb_make_readqpacket(struct hpsb_host *host, nodeid_t node, u64 addr); Modified: trunk/nodemgr.c ============================================================================== --- trunk/nodemgr.c (original) +++ trunk/nodemgr.c 2002-10-14 08:43:25.000000000 -0400 @@ -335,6 +335,9 @@ INIT_LIST_HEAD(&ne->list); INIT_LIST_HEAD(&ne->unit_directories); + + HPSB_TPOOL_INIT(&ne->tpool); + ne->host = host; ne->nodeid = nodeid; ne->guid = guid; @@ -1211,6 +1214,18 @@ return ne; } +struct node_entry *hpsb_check_nodeid(nodeid_t nodeid) +{ + struct node_entry *ne; + + if (down_trylock(&nodemgr_serialize)) + return NULL; + ne = find_entry_by_nodeid(nodeid); + up(&nodemgr_serialize); + + return ne; +} + /* 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 Modified: trunk/nodemgr.h ============================================================================== --- trunk/nodemgr.h (original) +++ trunk/nodemgr.h 2002-10-14 08:43:25.000000000 -0400 @@ -132,6 +132,8 @@ u32 capabilities; struct list_head unit_directories; + struct hpsb_tlabel_pool tpool; + const char *vendor_name; quadlet_t quadlets[0]; }; @@ -152,6 +154,10 @@ * fool-proof by itself, since the nodeid can change. */ struct node_entry *hpsb_nodeid_get_entry(nodeid_t nodeid); +/* Same as above except that it will not block waiting for the nodemgr + * serialize semaphore. */ +struct node_entry *hpsb_check_nodeid(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 Modified: trunk/hosts.c ============================================================================== --- trunk/hosts.c (original) +++ trunk/hosts.c 2002-10-14 08:43:25.000000000 -0400 @@ -133,8 +133,7 @@ INIT_LIST_HEAD(&h->pending_packets); spin_lock_init(&h->pending_pkt_lock); - sema_init(&h->tlabel_count, 64); - spin_lock_init(&h->tlabel_lock); + HPSB_TPOOL_INIT(&h->tpool); atomic_set(&h->generation, 0); Modified: trunk/hosts.h ============================================================================== --- trunk/hosts.h (original) +++ trunk/hosts.h 2002-10-14 08:43:25.000000000 -0400 @@ -32,13 +32,6 @@ spinlock_t pending_pkt_lock; struct hpsb_queue_struct timeout_tq; - /* A bitmask where a set bit means that this tlabel is in use. - * FIXME - should be handled per node instead of per bus. */ - u32 tlabel_pool[2]; - struct semaphore tlabel_count; - spinlock_t tlabel_lock; - u32 tlabel_current; - unsigned char iso_listen_count[64]; int node_count; /* number of identified nodes on this bus */ @@ -64,6 +57,8 @@ u8 *speed_map; struct csr_control csr; + struct hpsb_tlabel_pool tpool; + struct hpsb_host_driver *driver; struct pci_dev *pdev; Modified: trunk/sbp2.c ============================================================================== --- trunk/sbp2.c (original) +++ trunk/sbp2.c 2002-10-14 08:43:25.000000000 -0400 @@ -790,7 +790,12 @@ hpsb_node_fill_packet(ne, packet); - packet->tlabel = get_tlabel(hi->host, packet->node_id, 0); + if (hpsb_get_tlabel(packet, 0)) { + list_add_tail(&request_packet->list, &hi->sbp2_req_free); + SBP2_ERR("sbp2util_allocate_request_packet - no tlabels available!"); + sbp2_spin_unlock(&hi->sbp2_request_packet_lock, flags); + return NULL; + } if (!data_size) { fill_async_writequad(packet, addr, data); @@ -830,8 +835,7 @@ * Free the tlabel, and return the packet to the free pool. */ sbp2_spin_lock(&hi->sbp2_request_packet_lock, flags); - free_tlabel(hi->host, LOCAL_BUS | request_packet->packet->node_id, - request_packet->packet->tlabel); + hpsb_free_tlabel(request_packet->packet); list_del(&request_packet->list); list_add_tail(&request_packet->list, &hi->sbp2_req_free); sbp2_spin_unlock(&hi->sbp2_request_packet_lock, flags); Modified: trunk/ieee1394_types.h ============================================================================== --- trunk/ieee1394_types.h (original) +++ trunk/ieee1394_types.h 2002-10-14 08:43:25.000000000 -0400 @@ -7,6 +7,7 @@ #include <linux/version.h> #include <linux/list.h> #include <linux/init.h> +#include <asm/semaphore.h> #include <asm/byteorder.h> @@ -61,6 +62,22 @@ #define HPSB_PREPARE_WORK(x,y,z) PREPARE_WORK(x,y,z) #endif +/* Transaction Label handling */ +struct hpsb_tlabel_pool { + u64 pool; + spinlock_t lock; + u8 next; + struct semaphore count; +}; + +#define HPSB_TPOOL_INIT(_tp) \ +do { \ + sema_init(&(_tp)->count, 64); \ + spin_lock_init(&(_tp)->lock); \ + (_tp)->next = 0; \ + (_tp)->pool = 0; \ +} while(0) + typedef u32 quadlet_t; typedef u64 octlet_t; |