diff options
author | Ben Collins <bcollins@debian.org> | 2005-07-09 20:01:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-10 12:23:23 -0700 |
commit | 1934b8b6561ee7804b0a671b48cf642fcd936b2c (patch) | |
tree | 25c975176441aceedd2faae515121374f6f75750 /drivers/ieee1394/iso.c | |
parent | f179bc77d09b9087bfc559d0368bba350342ac76 (diff) | |
download | op-kernel-dev-1934b8b6561ee7804b0a671b48cf642fcd936b2c.zip op-kernel-dev-1934b8b6561ee7804b0a671b48cf642fcd936b2c.tar.gz |
[PATCH] Sync up ieee-1394
Lots of this patch is trivial code cleanups (static vars were being
intialized to 0, etc).
There's also some fixes for ISO transmits (max buffer handling).
Aswell, we have a few fixes to disable IRM capabilites correctly. We've
also disabled, by default some generally unused EXPORT symbols for the
sake of cleanliness in the kernel. However, instead of removing them
completely, we felt it necessary to have a config option that allowed
them to be enabled for the many projects outside of the main kernel tree
that use our API for driver development.
The primary reason for this patch is to revert a MODE6->MODE10 RBC
conversion patch from the SCSI maintainers. The new conversions handled
directly in the scsi layer do not seem to work for SBP2. This patch
reverts to our old working code so that users can enjoy using Firewire
disks and dvd drives again.
We are working with the SCSI maintainers to resolve this issue outside
of the main kernel tree. We'll merge the patch once the SCSI layer's
handling of the MODE10 conversion is working for us.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/ieee1394/iso.c')
-rw-r--r-- | drivers/ieee1394/iso.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c index f057591..615541b 100644 --- a/drivers/ieee1394/iso.c +++ b/drivers/ieee1394/iso.c @@ -62,10 +62,10 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i 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 = 1; - else if ((irq_interval < 0) || (irq_interval > buf_packets / 4)) - irq_interval = buf_packets / 4; if (channel < -1 || channel >= 64) return NULL; @@ -106,6 +106,7 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i } atomic_set(&iso->overflows, 0); + iso->bytes_discarded = 0; iso->flags = 0; iso->prebuffer = 0; @@ -241,12 +242,12 @@ int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer) iso->xmit_cycle = cycle; if (prebuffer < 0) - prebuffer = iso->buf_packets; + prebuffer = iso->buf_packets - 1; else if (prebuffer == 0) prebuffer = 1; - if (prebuffer > iso->buf_packets) - prebuffer = iso->buf_packets; + if (prebuffer >= iso->buf_packets) + prebuffer = iso->buf_packets - 1; iso->prebuffer = prebuffer; @@ -395,7 +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 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); @@ -403,10 +404,13 @@ void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len, if (iso->n_ready_packets == iso->buf_packets) { /* overflow! */ atomic_inc(&iso->overflows); + /* Record size of this discarded packet */ + iso->bytes_discarded += total_len; } else { struct hpsb_iso_packet_info *info = &iso->infos[iso->pkt_dma]; info->offset = offset; info->len = len; + info->total_len = total_len; info->cycle = cycle; info->channel = channel; info->tag = tag; @@ -437,6 +441,17 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_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->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); + iso->bytes_discarded = 0; + } + } } spin_unlock_irqrestore(&iso->lock, flags); return rv; |