⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal_x86.c

📁 usb isp1761驱动源代码 可编进内核。
💻 C
📖 第 1 页 / 共 3 页
字号:
    pci_unregister_driver (&isp1761_pci_driver);
    memset(isp1761_loc_dev,0,sizeof(isp1761_loc_dev));
} 


/*--------------------------------------------------------------*
 *
 *  Module dtatils: isp1761_pci_probe
 *
 * PCI probe function of ISP1761
 * This function is called from PCI Driver as an initialization function
 * when it founds the PCI device. This functions initializes the information
 * for the 3 Controllers with the assigned resources and tests the register
 * access to these controllers and do a software reset and makes them ready
 * for the drivers to play with them.
 *
 *  Input: 
 *              struct pci_dev *dev                     ----> PCI Devie data structure 
 *      const struct pci_device_id *id  ----> PCI Device ID 
 *  Output void
 *
 *  Called by: system function module_cleanup 
 * 
 * 
 * 
 --------------------------------------------------------------**/

    static int __devinit
isp1761_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
    u8 latency, limit;
    __u32       reg_data = 0;
    int retry_count;
    struct isp1761_dev  *loc_dev;
    void *address = 0;
    int length = 0;
    int status = 1;
    hal_entry("%s: Entered\n",__FUNCTION__);

    hal_init(("isp1761_pci_probe(dev=%p)\n",dev));
    if (pci_enable_device(dev) < 0){
        err("failed in enabing the device\n");
        return -ENODEV;
    }
    if (!dev->irq) {
        err("found ISP1761 device with no IRQ assigned."); 
        err("check BIOS settings!");
        return -ENODEV;
    }
    /* Grab the PLX PCI mem maped port start address we need  */
    pci_io_base = pci_resource_start(dev, 0);
    hal_init(("isp1761 pci IO Base= %x\n", pci_io_base));;

    iolength = pci_resource_len(dev, 0);
    hal_init(("isp1761 pci io length %d\n", iolength));
    if(!request_mem_region(pci_io_base,iolength,"ISP1761 IO MEM")){
        err("host controller already in use1\n");
        return -EBUSY;
    }   
    iobase = ioremap_nocache(pci_io_base, iolength);
    if(!iobase){
        err("can not map io memory to system memory\n");
        release_mem_region(pci_io_base,iolength);
        return -ENOMEM;
    }
    /* Grab the PLX PCI shared memory of the ISP 1761 we need  */
    pci_mem_phy0 = pci_resource_start (dev, 3);         
    hal_init(("isp1761 pci base address = %x\n", pci_mem_phy0));

    /* Get the Host Controller IO and INT resources
     */
    loc_dev = &(isp1761_loc_dev[ISP1761_HC]);
    loc_dev->irq = dev->irq;
    loc_dev->io_base = pci_mem_phy0;
    loc_dev->start   =  pci_mem_phy0;
    loc_dev->length  = pci_mem_len;
    loc_dev->io_len = pci_mem_len; /*64K*/
    loc_dev->index = ISP1761_HC;/*zero*/

    length = pci_resource_len(dev,3);
    if(length < pci_mem_len){
        err("memory length for this resource is less than required\n");
        release_mem_region(pci_io_base, iolength);
        iounmap(iobase);
        return  -ENOMEM;                                

    }
    loc_dev->io_len = length; 
    if(check_mem_region(loc_dev->io_base,length)<0){
        err("host controller already in use\n");
        release_mem_region(pci_io_base, iolength);
        iounmap(iobase);
        return -EBUSY;
    }
    if(!request_mem_region(loc_dev->io_base, length,isp1761_driver_name)){
        err("host controller already in use\n");
        release_mem_region(pci_io_base, iolength);
        iounmap(iobase);
        return -EBUSY;

    }

    /*map available memory*/
    address = ioremap_nocache(pci_mem_phy0,length);
    if(address == NULL){
        err("memory map problem\n");
        release_mem_region(pci_io_base, iolength);
        iounmap(iobase);
        release_mem_region(loc_dev->io_base,length);
        return -ENOMEM;
    } 

    loc_dev->baseaddress = (u8*)address;
    loc_dev->dmabase = (u8*)iobase;

    hal_init(("isp1761 HC MEM Base= %p irq = %d\n", 
                loc_dev->baseaddress,loc_dev->irq));
#ifdef ISP1761_DEVICE   

    /*initialize device controller framework*/  
    loc_dev = &(isp1761_loc_dev[ISP1761_DC]);
    loc_dev->irq = dev->irq;
    loc_dev->io_base = pci_mem_phy0;
    loc_dev->start   = pci_mem_phy0;
    loc_dev->length  = pci_mem_len;
    loc_dev->io_len = pci_mem_len;
    loc_dev->index = ISP1761_DC;
    loc_dev->baseaddress = address;
    loc_dev->active = 1;
    memcpy(loc_dev->name,"isp1761_dev",11);
    loc_dev->name[12] = '\0';


    {
        u32 chipid = 0;
        chipid = readl(address + 0x270);
        info("pid %04x, vid %04x\n", (chipid & 0xffff), (chipid >> 16));
    }   
    hal_init(("isp1761 DC MEM Base= %lx irq = %d\n", 
                loc_dev->io_base,loc_dev->irq));
    /* Get the OTG Controller IO and INT resources
     * OTG controller resources are same as Host Controller resources
     */
    loc_dev = &(isp1761_loc_dev[ISP1761_OTG]);
    loc_dev->irq = dev->irq; /*same irq also*/
    loc_dev->io_base = pci_mem_phy0;
    loc_dev->start   =  pci_mem_phy0;
    loc_dev->length  = pci_mem_len;     
    loc_dev->io_len = pci_mem_len;
    loc_dev->index = ISP1761_OTG; 
    loc_dev->baseaddress = address; /*having the same address as of host*/
    loc_dev->active = 1;
    memcpy(loc_dev->name,"isp1761_otg",11);
    loc_dev->name[12] = '\0';

    hal_init(("isp1761 OTG MEM Base= %lx irq = %x\n", 
                loc_dev->io_base,loc_dev->irq));

#endif
    /* bad pci latencies can contribute to overruns */ 
    pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
    if (latency) {
        pci_read_config_byte (dev, PCI_MAX_LAT, &limit);
        if (limit && limit < latency) {
            dbg ("PCI latency reduced to max %d", limit);
            pci_write_config_byte (dev, PCI_LATENCY_TIMER, limit);
            isp1761_pci_latency = limit;
        } else {
            /* it might already have been reduced */
            isp1761_pci_latency = latency;
        }
    }

    /* Try to check whether we can access Scratch Register of
     * Host Controller or not. The initial PCI access is retried until 
     * local init for the PCI bridge is completed 
     */

    loc_dev = &(isp1761_loc_dev[ISP1761_HC]);
    retry_count = PCI_ACCESS_RETRY_COUNT;
    while((reg_data != 0xFACE) && retry_count) {
        /*by default host is in 16bit mode, so
         * io operations at this stage must be 16 bit
         * */
        isp1761_reg_write16(loc_dev, HC_SCRATCH_REG, 0xFACE);
        udelay(100);
        reg_data = isp1761_reg_read16(loc_dev, HC_SCRATCH_REG,reg_data);
        retry_count--;
    }

    /* Host Controller presence is detected by writing to scratch register
     * and reading back and checking the contents are same or not
     */
    if(reg_data != 0xFACE) {
        err("%s scratch register mismatch %x",
                isp1761_driver_name,reg_data);
        status = -ENODEV;
        goto clean;
    }

    memcpy(loc_dev->name, isp1761_driver_name, sizeof(isp1761_driver_name));
    loc_dev->name[sizeof(isp1761_driver_name)] = 0;
    loc_dev->active = 1;

    info("controller address %p\n", &dev->dev);
    /*keep a copy of pcidevice*/
    loc_dev->pcidev = dev;


    pci_set_master(dev);
    hal_data.irq_usage = 0;
    pci_set_drvdata (dev, loc_dev);
    hal_entry("%s: Exit\n",__FUNCTION__);
    return 1;

clean:
    release_mem_region(pci_io_base, iolength);
    iounmap(iobase);
    release_mem_region(loc_dev->io_base, loc_dev->io_len);
    iounmap(loc_dev->baseaddress);
    hal_entry("%s: Exit\n",__FUNCTION__);
    return status;
} /* End of isp1761_pci_probe */


/*--------------------------------------------------------------*
 *
 *  Module dtatils: isp1761_pci_remove
 *
 * PCI cleanup function of ISP1761
 * This function is called from PCI Driver as an removal function
 * in the absence of PCI device or a de-registration of driver.
 * This functions checks the registerd drivers (HCD, DCD, OTG) and calls
 * the corresponding removal functions. Also initializes the local variables
 * to zero.
 *
 *  Input: 
 *              struct pci_dev *dev                     ----> PCI Devie data structure 
 *    
 *  Output void
 *
 *  Called by: system function module_cleanup 
 * 
 * 
 * 
 --------------------------------------------------------------*/
    static void __devexit
isp1761_pci_remove (struct pci_dev *dev)
{
    struct isp1761_dev  *loc_dev;
    hal_init(("isp1761_pci_remove(dev=%p)\n",dev));
    /*Lets handle the host first*/
    loc_dev  = &isp1761_loc_dev[ISP1761_HC];
    /*free the memory occupied by host*/
    release_mem_region(loc_dev->io_base, loc_dev->io_len);      
    release_mem_region(pci_io_base, iolength);
    /*unmap the occupied memory resources*/
    iounmap(loc_dev->baseaddress);
    /* unmap the occupied io resources*/
    iounmap(iobase); 
    return;
} /* End of isp1761_pci_remove */

/*--------------------------------------------------------------*
 *
 *  Module dtatils: isp1761_pci_suspend
 *
 * PCI suspend function of ISP1761
 * This function is called from PCI Driver.
 * This functions checks the registerd drivers (HCD, DCD, OTG) and calls
 * the corresponding suspend functions if present. 
 *  Input: 
 *              struct pci_dev *dev                     ----> PCI Devie data structure 
 *    
 *  Output void
 *
 *  Called by: system function 
 * 
 * 
 * 
 --------------------------------------------------------------*/

static int isp1761_pci_suspend (struct pci_dev *dev, __u32 state) 
{
    struct isp1761_dev  *loc_dev;
    int                 index;

    hal_init(("isp1761_pci_suspend(dev=%p, state = %x)\n",dev, state));


    loc_dev = (struct isp1761_dev *)pci_get_drvdata(dev);

    /* For each controller check whether driver is registerd
     * or not. If registerd call the suspend function if it is
     * present
     */
    for(index=ISP1761_1ST_DEV;index<ISP1761_LAST_DEV;(index++,loc_dev++)) {
        if(loc_dev->driver && loc_dev->driver->suspend) {
            loc_dev->driver->suspend(loc_dev);
        }
    }

    return 0;
} /* End of isp1761_pci_suspend */


/*--------------------------------------------------------------*
 *
 *  Module dtatils: isp1761_pci_suspend
 *
 *  PCI resume function of ISP1761
 * This function is called from PCI Driver.
 * This functions checks the registerd drivers (HCD, DCD, OTG) and calls
 * the corresponding resume functions if present.  
 *  Input: 
 *              struct pci_dev *dev                     ----> PCI Devie data structure 
 *    
 *  Output void
 *
 *  Called by: system function
 * 
 * 
 --------------------------------------------------------------*/
static int isp1761_pci_resume (struct pci_dev *dev)
{
    struct isp1761_dev  *loc_dev;
    int                 index;
    hal_init(("isp1362_pci_resume(dev=%p)\n",dev));
    loc_dev = (struct isp1761_dev *)pci_get_drvdata(dev);

    /* For each controller check whether driver is registerd
     * or not. If registerd call the resume function if it is
     * present
     */
    for(index=ISP1761_1ST_DEV;index<ISP1761_LAST_DEV;(index++,loc_dev++)) {
        if(loc_dev->driver && loc_dev->driver->resume) {
            loc_dev->driver->resume(loc_dev);
        }
    }

    return 0;

} /* End of isp1362_pci_resume */



EXPORT_SYMBOL(isp1761_reg_write16);
EXPORT_SYMBOL(isp1761_reg_read16);
EXPORT_SYMBOL(isp1761_reg_read32);
EXPORT_SYMBOL(isp1761_reg_write32);
EXPORT_SYMBOL(isp1761_request_irq);
EXPORT_SYMBOL(isp1761_mem_read);
EXPORT_SYMBOL(isp1761_mem_write);
EXPORT_SYMBOL(isp1761_free_irq);
EXPORT_SYMBOL(isp1761_register_driver);
EXPORT_SYMBOL(isp1761_unregister_driver);

MODULE_AUTHOR (DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE ("GPL");

module_init (isp1761_pci_module_init);
module_exit (isp1761_pci_module_cleanup);


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -