summaryrefslogtreecommitdiffstats
path: root/sys/dev/firewire
diff options
context:
space:
mode:
authorsimokawa <simokawa@FreeBSD.org>2007-07-15 13:00:29 +0000
committersimokawa <simokawa@FreeBSD.org>2007-07-15 13:00:29 +0000
commit9bdbb066cbe14b1ce7f70c8f6989cd5b9d568543 (patch)
tree1bd47908e9b3e386865b38283c3830d6240c0d16 /sys/dev/firewire
parentfdb167ed99c6005f2ee4dcefb29495fa599a401e (diff)
downloadFreeBSD-src-9bdbb066cbe14b1ce7f70c8f6989cd5b9d568543.zip
FreeBSD-src-9bdbb066cbe14b1ce7f70c8f6989cd5b9d568543.tar.gz
Improve acquisition of transaction labels.
- Keep last transaction label for each destination. - If the next label is not free, just give up. - This should reduce CPU load for TX on if_fwip under heavy load. Approved by: re (hrs)
Diffstat (limited to 'sys/dev/firewire')
-rw-r--r--sys/dev/firewire/firewire.c36
-rw-r--r--sys/dev/firewire/firewirereg.h1
2 files changed, 17 insertions, 20 deletions
diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c
index 4015d56..9421b62 100644
--- a/sys/dev/firewire/firewire.c
+++ b/sys/dev/firewire/firewire.c
@@ -1711,38 +1711,34 @@ fw_attach_dev(struct firewire_comm *fc)
static int
fw_get_tlabel(struct firewire_comm *fc, struct fw_xfer *xfer)
{
- u_int i;
+ u_int dst, new_tlabel;
struct fw_xfer *txfer;
int s;
- static uint32_t label = 0;
+ dst = xfer->send.hdr.mode.hdr.dst & 0x3f;
s = splfw();
FW_GLOCK(fc);
- for( i = 0 ; i < 0x40 ; i ++){
- label = (label + 1) & 0x3f;
- STAILQ_FOREACH(txfer, &fc->tlabels[label], tlabel)
- if (txfer->send.hdr.mode.hdr.dst ==
- xfer->send.hdr.mode.hdr.dst)
+ new_tlabel = (fc->last_tlabel[dst] + 1) & 0x3f;
+ STAILQ_FOREACH(txfer, &fc->tlabels[new_tlabel], tlabel)
+ if ((txfer->send.hdr.mode.hdr.dst & 0x3f) == dst)
break;
- if(txfer == NULL) {
- xfer->tl = label;
- xfer->send.hdr.mode.hdr.tlrt = label << 2;
- STAILQ_INSERT_TAIL(&fc->tlabels[label], xfer, tlabel);
- FW_GUNLOCK(fc);
- splx(s);
- if (firewire_debug > 1)
- printf("fw_get_tlabel: dst=%d tl=%d\n",
- xfer->send.hdr.mode.hdr.dst, label);
- /* note: label may be incremanted after unlock */
- return(xfer->tl);
- }
+ if(txfer == NULL) {
+ fc->last_tlabel[dst] = new_tlabel;
+ STAILQ_INSERT_TAIL(&fc->tlabels[new_tlabel], xfer, tlabel);
+ FW_GUNLOCK(fc);
+ splx(s);
+ xfer->tl = new_tlabel;
+ xfer->send.hdr.mode.hdr.tlrt = new_tlabel << 2;
+ if (firewire_debug > 1)
+ printf("fw_get_tlabel: dst=%d tl=%d\n", dst, new_tlabel);
+ return (new_tlabel);
}
FW_GUNLOCK(fc);
splx(s);
if (firewire_debug > 1)
printf("fw_get_tlabel: no free tlabel\n");
- return(-1);
+ return (-1);
}
static void
diff --git a/sys/dev/firewire/firewirereg.h b/sys/dev/firewire/firewirereg.h
index d2d9d65..0ceb5a2 100644
--- a/sys/dev/firewire/firewirereg.h
+++ b/sys/dev/firewire/firewirereg.h
@@ -133,6 +133,7 @@ struct firewire_comm{
struct fw_xferq
*arq, *atq, *ars, *ats, *it[FW_MAX_DMACH],*ir[FW_MAX_DMACH];
struct fw_xferlist tlabels[0x40];
+ u_char last_tlabel[0x40];
STAILQ_HEAD(, fw_bind) binds;
STAILQ_HEAD(, fw_device) devices;
u_int sid_cnt;
OpenPOWER on IntegriCloud