lkml.org 
[lkml]   [2002]   [Mar]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
SubjectRe: [PATCH 2.5.5] Conversion of hp100 to new PCI interface
From
On Wed, Feb 27, 2002 at 08:28:13PM -0500, Jeff Garzik wrote:
> If you just wanted to redo the patch storing the pci_alloc_mapping
> mapping values in struct hp100_private, the patch is otherwise ok...

Sorry, was busy. Still need to go through my IrDA patches, but
here is the hp100 patch "the right way". Patch against 2.5.6-pre1,
tested on J2585B.
Have fun...

Jean
diff -u -p linux/drivers/net/hp100_vb.c linux/drivers/net/hp100.c
--- linux/drivers/net/hp100_vb.c Tue Feb 26 16:24:51 2002
+++ linux/drivers/net/hp100.c Mon Mar 4 12:03:23 2002
@@ -83,8 +83,6 @@
**
*/

-#error Please convert me to Documentation/DMA-mapping.txt
-
#define HP100_DEFAULT_PRIORITY_TX 0

#undef HP100_DEBUG
@@ -212,8 +210,8 @@ struct hp100_private {
hp100_ring_t rxring[MAX_RX_PDL];
hp100_ring_t txring[MAX_TX_PDL];

- u_int *page_vaddr; /* Virtual address of allocated page */
u_int *page_vaddr_algn; /* Aligned virtual address of allocated page */
+ u_long whatever_offset; /* Offset to bus/phys/dma address */
int rxrcommit; /* # Rx PDLs commited to adapter */
int txrcommit; /* # Tx PDLs commited to adapter */
};
@@ -350,6 +348,18 @@ static void hp100_clean_txring(struct ne
static void hp100_RegisterDump(struct net_device *dev);
#endif

+/* Conversion to new PCI API :
+ * Convert an address in a kernel buffer to a bus/phys/dma address.
+ * This work *only* for memory fragments part of lp->page_vaddr,
+ * because it was properly DMA allocated via pci_alloc_consistent(),
+ * so we just need to "retreive" the original mapping to bus/phys/dma
+ * address - Jean II */
+static inline dma_addr_t virt_to_whatever(struct net_device *dev, u32 * ptr)
+{
+ return ((u_long) ptr) +
+ ((struct hp100_private *) (dev->priv))->whatever_offset;
+}
+
/* TODO: This function should not really be needed in a good design... */
static void wait(void)
{
@@ -627,9 +637,20 @@ static int __init hp100_probe1(struct ne
local_mode = 3;
} else if (chip == HP100_CHIPID_LASSEN &&
(lsw & (HP100_BM_WRITE | HP100_BM_READ)) == (HP100_BM_WRITE | HP100_BM_READ)) {
+ /* Conversion to new PCI API :
+ * I don't have the doc, but I assume that the card
+ * can map the full 32bit address space.
+ * Also, we can have EISA Busmaster cards (not tested),
+ * so beware !!! - Jean II */
+ if((bus == HP100_BUS_PCI) &&
+ (pci_set_dma_mask(pci_dev, 0xffffffff))) {
+ /* Gracefully fallback to shared memory */
+ goto busmasterfail;
+ }
printk("hp100: %s: Busmaster mode enabled.\n", dev->name);
hp100_outw(HP100_MEM_EN | HP100_IO_EN | HP100_RESET_LB, OPTION_LSW);
} else {
+ busmasterfail:
#ifdef HP100_DEBUG
printk("hp100: %s: Card not configured for BM or BM not supported with this card.\n", dev->name);
printk("hp100: %s: Trying shared memory mode.\n", dev->name);
@@ -772,11 +793,14 @@ static int __init hp100_probe1(struct ne
* in the cards shared memory area. But currently, busmaster has been
* implemented/tested only with the lassen chip anyway... */
if (lp->mode == 1) { /* busmaster */
+ dma_addr_t page_baddr;
/* Get physically continous memory for TX & RX PDLs */
- if ((lp->page_vaddr = kmalloc(MAX_RINGSIZE + 0x0f, GFP_KERNEL)) == NULL)
+ /* Conversion to new PCI API :
+ * Pages are always aligned and zeroed, no need to it ourself.
+ * Doc says should be OK for EISA bus as well - Jean II */
+ if ((lp->page_vaddr_algn = pci_alloc_consistent(lp->pci_dev, MAX_RINGSIZE, &page_baddr)) == NULL)
return -ENOMEM;
- lp->page_vaddr_algn = ((u_int *) (((u_int) (lp->page_vaddr) + 0x0f) & ~0x0f));
- memset(lp->page_vaddr, 0, MAX_RINGSIZE + 0x0f);
+ lp->whatever_offset = ((u_long) page_baddr) - ((u_long) lp->page_vaddr_algn);

#ifdef HP100_DEBUG_BM
printk("hp100: %s: Reserved DMA memory from 0x%x to 0x%x\n", dev->name, (u_int) lp->page_vaddr_algn, (u_int) lp->page_vaddr_algn + MAX_RINGSIZE);
@@ -1189,7 +1213,7 @@ static void hp100_init_pdls(struct net_d
{
struct hp100_private *lp = (struct hp100_private *) dev->priv;
hp100_ring_t *ringptr;
- u_int *pageptr;
+ u_int *pageptr; /* Warning : increment by 4 - Jean II */
int i;

#ifdef HP100_DEBUG_B
@@ -1246,7 +1270,7 @@ static int hp100_init_rxpdl(struct net_d
dev->name, (unsigned) pdlptr);

ringptr->pdl = pdlptr + 1;
- ringptr->pdl_paddr = virt_to_bus(pdlptr + 1);
+ ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr + 1);
ringptr->skb = (void *) NULL;

/*
@@ -1257,7 +1281,7 @@ static int hp100_init_rxpdl(struct net_d
*/
/* Note that pdlptr+1 and not pdlptr is the pointer to the PDH */

- *(pdlptr + 2) = (u_int) virt_to_bus(pdlptr); /* Address Frag 1 */
+ *(pdlptr + 2) = (u_int) virt_to_whatever(dev, pdlptr); /* Address Frag 1 */
*(pdlptr + 3) = 4; /* Length Frag 1 */

return ((((MAX_RX_FRAG * 2 + 2) + 3) / 4) * 4);
@@ -1272,7 +1296,7 @@ static int hp100_init_txpdl(struct net_d
printk("hp100: %s: Init txpdl: Unaligned pdlptr 0x%x.\n", dev->name, (unsigned) pdlptr);

ringptr->pdl = pdlptr; /* +1; */
- ringptr->pdl_paddr = virt_to_bus(pdlptr); /* +1 */
+ ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr); /* +1 */
ringptr->skb = (void *) NULL;

return ((((MAX_TX_FRAG * 2 + 2) + 3) / 4) * 4);
@@ -1331,8 +1355,10 @@ static int hp100_build_rx_pdl(hp100_ring
(unsigned int) ringptr->skb->data);
#endif

+ /* Conversion to new PCI API : map skbuf data to PCI bus.
+ * Doc says it's OK for EISA as well - Jean II */
ringptr->pdl[0] = 0x00020000; /* Write PDH */
- ringptr->pdl[3] = ((u_int) virt_to_bus(ringptr->skb->data));
+ ringptr->pdl[3] = ((u_int) pci_map_single(((struct hp100_private *) (dev->priv))->pci_dev, ringptr->skb->data, MAX_ETHER_SIZE, PCI_DMA_FROMDEVICE));
ringptr->pdl[4] = MAX_ETHER_SIZE; /* Length of Data */

#ifdef HP100_DEBUG_BM
@@ -1585,7 +1611,6 @@ static int hp100_start_xmit_bm(struct sk

ringptr->skb = skb;
ringptr->pdl[0] = ((1 << 16) | i); /* PDH: 1 Fragment & length */
- ringptr->pdl[1] = (u32) virt_to_bus(skb->data); /* 1st Frag: Adr. of data */
if (lp->chip == HP100_CHIPID_SHASTA) {
/* TODO:Could someone who has the EISA card please check if this works? */
ringptr->pdl[2] = i;
@@ -1593,6 +1618,9 @@ static int hp100_start_xmit_bm(struct sk
/* In the PDL, don't use the padded size but the real packet size: */
ringptr->pdl[2] = skb->len; /* 1st Frag: Length of frag */
}
+ /* Conversion to new PCI API : map skbuf data to PCI bus.
+ * Doc says it's OK for EISA as well - Jean II */
+ ringptr->pdl[1] = ((u32) pci_map_single(lp->pci_dev, skb->data, ringptr->pdl[2], PCI_DMA_TODEVICE)); /* 1st Frag: Adr. of data */

/* Hand this PDL to the card. */
hp100_outl(ringptr->pdl_paddr, TX_PDA_L); /* Low Prio. Queue */
@@ -1641,6 +1669,8 @@ static void hp100_clean_txring(struct ne
dev->name, (u_int) lp->txrhead->skb->data,
lp->txrcommit, hp100_inb(TX_PDL), donecount);
#endif
+ /* Conversion to new PCI API : NOP */
+ pci_unmap_single(lp->pci_dev, (dma_addr_t) lp->txrhead->pdl[1], lp->txrhead->pdl[2], PCI_DMA_TODEVICE);
dev_kfree_skb_any(lp->txrhead->skb);
lp->txrhead->skb = (void *) NULL;
lp->txrhead = lp->txrhead->next;
@@ -1950,6 +1980,9 @@ static void hp100_rx_bm(struct net_devic
header = *(ptr->pdl - 1);
pkt_len = (header & HP100_PKT_LEN_MASK);

+ /* Conversion to new PCI API : NOP */
+ pci_unmap_single(lp->pci_dev, (dma_addr_t) ptr->pdl[3], MAX_ETHER_SIZE, PCI_DMA_FROMDEVICE);
+
#ifdef HP100_DEBUG_BM
printk("hp100: %s: rx_bm: header@0x%x=0x%x length=%d, errors=0x%x, dest=0x%x\n",
dev->name, (u_int) (ptr->pdl - 1), (u_int) header,
@@ -2910,7 +2943,7 @@ static void release_dev(int i)
release_region(d->base_addr, HP100_REGION_SIZE);

if (p->mode == 1) /* busmaster */
- kfree(p->page_vaddr);
+ pci_free_consistent(p->pci_dev, MAX_RINGSIZE + 0x0f, p->page_vaddr_algn, virt_to_whatever(d, p->page_vaddr_algn));
if (p->mem_ptr_virt)
iounmap(p->mem_ptr_virt);
kfree(d->priv);
\
 
 \ /
  Last update: 2005-03-22 13:24    [W:0.046 / U:7.832 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site