diff options
-rw-r--r-- | sys/dev/fxp/if_fxp.c | 38 | ||||
-rw-r--r-- | sys/dev/fxp/if_fxpreg.h | 4 | ||||
-rw-r--r-- | sys/pci/if_fxp.c | 38 | ||||
-rw-r--r-- | sys/pci/if_fxpreg.h | 4 |
4 files changed, 68 insertions, 16 deletions
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index 66e2fa0..95a937c 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_fxp.c,v 1.2 1995/12/01 22:41:56 davidg Exp $ + * $Id: if_fxp.c,v 1.3 1995/12/05 02:01:51 davidg Exp $ */ /* @@ -171,9 +171,14 @@ DATA_SET(pcidevice_set, fxp_device); /* * Number of DMA segments in a TxCB. Note that this is carefully - * chosen to make the total struct size an even power of two. + * chosen to make the total struct size an even power of two. It's + * critical that no TxCB be split across a page boundry since + * no attempt is made to allocate physically contiguous memory. + * + * XXX - don't forget to change the hard-coded constant in the + * fxp_cb_tx struct (defined in if_fxpreg.h), too! */ -#define FXP_NTXSEG 13 +#define FXP_NTXSEG 29 /* * Number of receive frame area buffers. These are large so chose @@ -449,6 +454,7 @@ txloop: * the transmit buffers descriptors with the physical address * and size of the mbuf. */ +tbdinit: for (m = mb_head, segment = 0; m != NULL; m = m->m_next) { if (m->m_len != 0) { if (segment == FXP_NTXSEG) @@ -460,14 +466,34 @@ txloop: } } if (m != NULL && segment == FXP_NTXSEG) { + struct mbuf *mn; + /* * We ran out of segments. We have to recopy this mbuf * chain first. */ - panic("fxp%d: ran out of segments", ifp->if_unit); - } else { - txp->tbd_number = segment; + MGETHDR(mn, M_DONTWAIT, MT_DATA); + if (mn == NULL) { + m_freem(mb_head); + return; + } + if (mb_head->m_pkthdr.len > MHLEN) { + MCLGET(mn, M_DONTWAIT); + if ((mn->m_flags & M_EXT) == 0) { + m_freem(mn); + m_freem(mb_head); + return; + } + } + m_copydata(mb_head, 0, mb_head->m_pkthdr.len, mtod(mn, caddr_t)); + mn->m_pkthdr.len = mn->m_len = mb_head->m_pkthdr.len; + m_freem(mb_head); + mb_head = mn; + goto tbdinit; } + + txp->tbd_number = segment; + /* * Finish the initialization of this TxCB. */ diff --git a/sys/dev/fxp/if_fxpreg.h b/sys/dev/fxp/if_fxpreg.h index 61c3a5f..7c7b81d 100644 --- a/sys/dev/fxp/if_fxpreg.h +++ b/sys/dev/fxp/if_fxpreg.h @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: if_fxpreg.h,v 1.1 1995/11/28 23:55:26 davidg Exp $ */ #define FXP_VENDORID_INTEL 0x8086 @@ -177,7 +177,7 @@ struct fxp_cb_tx { /* * The following isn't actually part of the TxCB. */ - volatile struct fxp_tbd tbd[13]; + volatile struct fxp_tbd tbd[29]; struct mbuf *mb_head; struct fxp_cb_tx *next; }; diff --git a/sys/pci/if_fxp.c b/sys/pci/if_fxp.c index 66e2fa0..95a937c 100644 --- a/sys/pci/if_fxp.c +++ b/sys/pci/if_fxp.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_fxp.c,v 1.2 1995/12/01 22:41:56 davidg Exp $ + * $Id: if_fxp.c,v 1.3 1995/12/05 02:01:51 davidg Exp $ */ /* @@ -171,9 +171,14 @@ DATA_SET(pcidevice_set, fxp_device); /* * Number of DMA segments in a TxCB. Note that this is carefully - * chosen to make the total struct size an even power of two. + * chosen to make the total struct size an even power of two. It's + * critical that no TxCB be split across a page boundry since + * no attempt is made to allocate physically contiguous memory. + * + * XXX - don't forget to change the hard-coded constant in the + * fxp_cb_tx struct (defined in if_fxpreg.h), too! */ -#define FXP_NTXSEG 13 +#define FXP_NTXSEG 29 /* * Number of receive frame area buffers. These are large so chose @@ -449,6 +454,7 @@ txloop: * the transmit buffers descriptors with the physical address * and size of the mbuf. */ +tbdinit: for (m = mb_head, segment = 0; m != NULL; m = m->m_next) { if (m->m_len != 0) { if (segment == FXP_NTXSEG) @@ -460,14 +466,34 @@ txloop: } } if (m != NULL && segment == FXP_NTXSEG) { + struct mbuf *mn; + /* * We ran out of segments. We have to recopy this mbuf * chain first. */ - panic("fxp%d: ran out of segments", ifp->if_unit); - } else { - txp->tbd_number = segment; + MGETHDR(mn, M_DONTWAIT, MT_DATA); + if (mn == NULL) { + m_freem(mb_head); + return; + } + if (mb_head->m_pkthdr.len > MHLEN) { + MCLGET(mn, M_DONTWAIT); + if ((mn->m_flags & M_EXT) == 0) { + m_freem(mn); + m_freem(mb_head); + return; + } + } + m_copydata(mb_head, 0, mb_head->m_pkthdr.len, mtod(mn, caddr_t)); + mn->m_pkthdr.len = mn->m_len = mb_head->m_pkthdr.len; + m_freem(mb_head); + mb_head = mn; + goto tbdinit; } + + txp->tbd_number = segment; + /* * Finish the initialization of this TxCB. */ diff --git a/sys/pci/if_fxpreg.h b/sys/pci/if_fxpreg.h index 61c3a5f..7c7b81d 100644 --- a/sys/pci/if_fxpreg.h +++ b/sys/pci/if_fxpreg.h @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: if_fxpreg.h,v 1.1 1995/11/28 23:55:26 davidg Exp $ */ #define FXP_VENDORID_INTEL 0x8086 @@ -177,7 +177,7 @@ struct fxp_cb_tx { /* * The following isn't actually part of the TxCB. */ - volatile struct fxp_tbd tbd[13]; + volatile struct fxp_tbd tbd[29]; struct mbuf *mb_head; struct fxp_cb_tx *next; }; |