Patch??: linux-2.5.6-pre1/drivers/scsi/advansys.c DMA-mapping fixes

Patch??: linux-2.5.6-pre1/drivers/scsi/advansys.c DMA-mapping fixes

Post by Adam J. Richte » Sat, 02 Mar 2002 01:50:13



        The following is my attempt to at porting
linux-2.5.6-pre1/drivers/scsi/advansys.c to the new DMA mapping
scheme described in linux-2.5.6-pre1/Documentation/DMA-mapping.txt.

        Since I do not have an advansys card and I'm a bit green
at doing these conversions, I would appreciate it someone who knows
the advansys driver could take a look at this stuff and either
tell me if I have missed something or take it from here.

--
Adam J. Richter     __     ______________   4880 Stevens Creek Blvd, Suite 104
a...@yggdrasil.com     \ /                  San Jose, California 95129-1034
+1 408 261-6630         | g g d r a s i l   United States of America
fax +1 408 261-6631      "Free Software For The Rest Of Us."

--- linux-2.5.6-pre1/drivers/scsi/advansys.c    Tue Feb 19 18:10:59 2002
+++ linux/drivers/scsi/advansys.c       Thu Feb 28 06:58:13 2002
@@ -752,8 +752,6 @@

 */

-#error Please convert me to Documentation/DMA-mapping.txt
-
 /*
  * --- Linux Version
  */
@@ -861,17 +859,6 @@
 #define ASC_DCNT  __u32         /* Unsigned Data count type. */
 #define ASC_SDCNT __s32         /* Signed Data count type. */

-/*
- * These macros are used to convert a virtual address to a
- * 32-bit value. This currently can be used on Linux Alpha
- * which uses 64-bit virtual address but a 32-bit bus address.
- * This is likely to break in the future, but doing this now
- * will give us time to change the HW and FW to handle 64-bit
- * addresses.
- */
-#define ASC_VADDR_TO_U32   virt_to_bus
-#define ASC_U32_TO_VADDR   bus_to_virt
-
 typedef unsigned char uchar;

 #ifndef NULL
@@ -1314,6 +1301,9 @@
     uchar               extra_bytes;
     uchar               res;
     ASC_DCNT            remain_bytes;
+
+    /* Everything below this line is not used by hardware.  */
+    Scsi_Cmnd          *scp;
 } ASC_QDONE_INFO;

 typedef struct asc_sg_list {
@@ -1351,6 +1341,8 @@
     ushort              next_sg_index;
 } ASC_SCSI_Q;

+struct adv_req;
+
 typedef struct asc_scsi_req_q {
     ASC_SCSIQ_1         r1;
     ASC_SCSIQ_2         r2;
@@ -2152,7 +2144,6 @@
  * addresses.
  */
 #define ADV_VADDR_TO_U32   virt_to_bus
-#define ADV_U32_TO_VADDR   bus_to_virt

 #define AdvPortAddr  ulong              /* Virtual memory address size */

@@ -3196,7 +3187,8 @@
      * End of microcode structure - 60 bytes. The rest of the structure
      * is used by the Adv Library and ignored by the microcode.
      */
-    ADV_VADDR   srb_ptr;
+
+    struct adv_req     *reqp;
     ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
     char        *vdata_addr;   /* Data buffer virtual address. */
     uchar       a_flag;
@@ -3249,8 +3241,6 @@
 STATIC void  DvcSleepMilliSecond(ADV_DCNT);
 STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
 STATIC void  DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
-STATIC ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
-                uchar *, ASC_SDCNT *, int);
 STATIC void  DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);

 /*
@@ -3464,16 +3454,6 @@
 extern ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
 extern ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;

-/*
- * DvcGetPhyAddr() flag arguments
- */
-#define ADV_IS_SCSIQ_FLAG       0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
-#define ADV_ASCGETSGLIST_VADDR  0x02 /* 'addr' is AscGetSGList() virtual addr */
-#define ADV_IS_SENSE_FLAG       0x04 /* 'addr' is sense virtual pointer */
-#define ADV_IS_DATA_FLAG        0x08 /* 'addr' is data virtual pointer */
-#define ADV_IS_SGLIST_FLAG      0x10 /* 'addr' is sglist virtual pointer */
-#define ADV_IS_CARRIER_FLAG     0x20 /* 'addr' is ADV_CARR_T pointer */
-
 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
 #define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
 #define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
@@ -4097,7 +4077,10 @@
     void                 *ioremap_addr;         /* I/O Memory remap address. */
     ushort               ioport;                /* I/O Port address. */
     ADV_CARR_T           *orig_carrp;           /* ADV_CARR_T memory block. */
+    dma_addr_t          carrp_dma;
     adv_req_t            *orig_reqp;            /* adv_req_t memory block. */
+    dma_addr_t          reqp_dma;
+    size_t              reqp_size;
     adv_req_t            *adv_reqp;             /* Request structures. */
     adv_sgblk_t          *adv_sgblkp;           /* Scatter-gather structures. */
     ushort               bios_signature;        /* BIOS Signature. */
@@ -4196,6 +4179,18 @@
     ASC_IS_PCI,
 };

+#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,4,0) && defined(MODULE)
+static struct pci_device_id advansys_pci_tbl[] __initdata = {
+    { ADV_PCI_VENDOR_ID, ASC_PCI_DEVICE_ID_1100, PCI_ANY_ID, PCI_ANY_ID },
+    { ADV_PCI_VENDOR_ID, ASC_PCI_DEVICE_ID_1200, PCI_ANY_ID, PCI_ANY_ID },
+    { ADV_PCI_VENDOR_ID, ASC_PCI_DEVICE_ID_1300, PCI_ANY_ID, PCI_ANY_ID },
+    { ADV_PCI_VENDOR_ID, ASC_PCI_DEVICE_ID_2300, PCI_ANY_ID, PCI_ANY_ID },
+    { ADV_PCI_VENDOR_ID, ASC_PCI_DEVICE_ID_2500, PCI_ANY_ID, PCI_ANY_ID },
+    { }                                /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
+#endif
+
 /*
  * Used with the LILO 'advansys' option to eliminate or
  * limit I/O port probing at boot time, cf. advansys_setup().
@@ -4281,6 +4276,46 @@
 STATIC void         asc_prt_hex(char *f, uchar *, int);
 #endif /* ADVANSYS_DEBUG */

+static void *alloc_consistent(struct pci_dev *pcidev, size_t size,
+                             dma_addr_t *dma_handle)
+{
+       if (pcidev == NULL) {   /* not PCI bus */
+               void *result = kmalloc(size, GFP_ATOMIC);
+               *dma_handle = (dma_addr_t) result;
+               return result;
+       } else
+               return pci_alloc_consistent(pcidev, size, dma_handle);
+}
+
+static void free_consistent(struct pci_dev *pcidev, size_t size,
+                           void *vaddr, dma_addr_t dma_handle)
+{
+       if (pcidev == NULL)
+               kfree(vaddr);   /* not PCI bus */
+       else
+               pci_free_consistent(pcidev, size, vaddr, dma_handle);
+}
+
+static inline __u32
+ptr_to_dma32le(dma_addr_t dma_base, void *ptr_base, void *ptr)
+{
+       return cpu_to_le32(dma_base + (ptr - ptr_base));
+}
+
+static inline void *
+dma32le_to_ptr(dma_addr_t dma_base, void *ptr_base, __u32 dma_le32)
+{
+       return ptr_base + (le32_to_cpu(dma_le32) - dma_base);
+}
+
+static inline ADV_CARR_T *
+dma_to_carrp(ADV_DVC_VAR *var, __u32 dma_le32)
+{
+       struct asc_board *boardp = var->drv_ptr;
+       return dma32le_to_ptr(boardp->carrp_dma, boardp->orig_carrp, dma_le32);
+}
+
+

 /*
  * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
@@ -4727,7 +4762,9 @@
                             pci_device_id_cnt++;
                         } else {
 #if ASC_LINUX_KERNEL24
-                            if (pci_enable_device(pci_devp) == 0) {
+                            if (pci_enable_device(pci_devp) == 0 &&
+                               /* Board is limited to 32 bit DMA addresses: */
+                               pci_set_dma_mask(pci_devp, 0xffffffff) == 0) {
                                 pci_devicep[pci_card_cnt_max++] = pci_devp;
                             }
 #elif ASC_LINUX_KERNEL22
@@ -5544,8 +5581,9 @@
                  * Allocate buffer carrier structures. The total size
                  * is about 4 KB, so allocate all at once.
                  */
-                carrp =
-                    (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
+               carrp = alloc_consistent(pci_devp, ADV_CARRIER_BUFSIZE,
+                                        &boardp->carrp_dma);
+
                 ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp);

                 if (carrp == NULL) {
@@ -5561,8 +5599,10 @@
                 for (req_cnt = adv_dvc_varp->max_host_qng;
                     req_cnt > 0; req_cnt--) {

-                    reqp = (adv_req_t *)
-                        kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
+                   boardp->reqp_size = sizeof(adv_req_t) * req_cnt;
+                   reqp = alloc_consistent(pci_devp,
+                                           boardp->reqp_size,
+                                           &boardp->reqp_dma);

                     ASC_DBG3(1,
                         "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n",
@@ -5614,14 +5654,23 @@
                         boardp->id);
                     err_code = ADV_ERROR;
                 } else if (reqp == NULL) {
-                    kfree(carrp);
+                   free_consistent(shp->pci_dev,
+                                   ADV_CARRIER_BUFSIZE,
+                                   carrp,
+                                   boardp->carrp_dma);
                     ASC_PRINT1(
 "advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n",
                         boardp->id);
                     err_code = ADV_ERROR;
                 } else if (boardp->adv_sgblkp == NULL) {
-                    kfree(carrp);
-                    kfree(reqp);
+                   free_consistent(shp->pci_dev,
+                                   ADV_CARRIER_BUFSIZE,
+                                   carrp,
+                                   boardp->carrp_dma);
+                   free_consistent(shp->pci_dev,
+                                   boardp->reqp_size,
+                                   reqp,
+                                   boardp->reqp_dma);
                     ASC_PRINT1(
 "advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
                         boardp->id);
@@ -5679,11 +5728,17 @@
                 if (ASC_WIDE_BOARD(boardp)) {
                     iounmap(boardp->ioremap_addr);
                     if (boardp->orig_carrp) {
-                        kfree(boardp->orig_carrp);
-                        boardp->orig_carrp = NULL;
+                       free_consistent(shp->pci_dev,
+                                       ADV_CARRIER_BUFSIZE,
+                                       boardp->orig_carrp,
+                                       boardp->carrp_dma);
+                       boardp->orig_carrp = NULL;
                     }
                     if (boardp->orig_reqp) {
-                        kfree(boardp->orig_reqp);
+                       free_consistent(shp->pci_dev,
+                                       boardp->reqp_size,
+                                       boardp->orig_reqp,
+                                       boardp->reqp_dma);
                         boardp->orig_reqp = boardp->adv_reqp = NULL;
                     }
                     while ((sgp = boardp->adv_sgblkp) != NULL)
@@ -5734,11 +5789,15 @@

         iounmap(boardp->ioremap_addr);
         if (boardp->orig_carrp) {
-            kfree(boardp->orig_carrp);
+          
...

read more »

 
 
 

Patch??: linux-2.5.6-pre1/drivers/scsi/advansys.c DMA-mapping fixes

Post by John Covic » Tue, 05 Mar 2002 17:30:09


I got the following error when trying to install the advansys scsi
driver as a module:

depmod:         virt_to_bus_not_defined_use_pci_map

Any assistance would be appreciated.


Quote:>    The following is my attempt to at porting
> linux-2.5.6-pre1/drivers/scsi/advansys.c to the new DMA mapping
> scheme described in linux-2.5.6-pre1/Documentation/DMA-mapping.txt.

>    Since I do not have an advansys card and I'm a bit green
> at doing these conversions, I would appreciate it someone who knows
> the advansys driver could take a look at this stuff and either
> tell me if I have missed something or take it from here.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

Patch??: linux-2.5.6-pre1/drivers/scsi/advansys.c DMA-mapping fixes

Post by John Covic » Tue, 05 Mar 2002 23:40:08


Yup, after the patch is applied I get the error -- without the patch
it won't even compile.


> >I got the following error when trying to install the advansys scsi
> >driver as a module:

> >depmod:         virt_to_bus_not_defined_use_pci_map

>    Do you mean that you get this error after applying my patch?

> Adam J. Richter     __     ______________   4880 Stevens Creek Blvd, Suite 104

> +1 408 261-6630         | g g d r a s i l   United States of America
> fax +1 408 261-6631      "Free Software For The Rest Of Us."

--
         John Covici

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/