📄 hal_x86.c
字号:
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 + -