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

📄 hp100.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
          ioaddr = pci_dev -> base_address[ 0 ] & ~3;          if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;          pci_read_config_word( pci_dev, PCI_COMMAND, &pci_command );          if ( !( pci_command & PCI_COMMAND_IO ) ) {#ifdef HP100_DEBUG            printk( "hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name );#endif            pci_command |= PCI_COMMAND_IO;            pci_write_config_word( pci_dev, PCI_COMMAND, pci_command );          }          if ( !( pci_command & PCI_COMMAND_MASTER ) ) {#ifdef HP100_DEBUG            printk( "hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name );#endif            pci_command |= PCI_COMMAND_MASTER;            pci_write_config_word( pci_dev, PCI_COMMAND, pci_command );          }#ifdef HP100_DEBUG          printk( "hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr );#endif	  if ( hp100_probe1( dev, ioaddr, HP100_BUS_PCI, pci_dev ) == 0 )	    return 0;        }      }      #else /* old PCI interface */      for ( pci_index = pci_start_index & 7; pci_index < 8; pci_index++ )        {          u_char pci_bus, pci_device_fn;          u_short pci_command;          int pci_id_index;	  for ( pci_id_index = 0; pci_id_index < HP100_PCI_IDS_SIZE; pci_id_index++ )            if ( pcibios_find_device( hp100_pci_ids[ pci_id_index ].vendor,            			      hp100_pci_ids[ pci_id_index ].device,                                      pci_index, &pci_bus,                                      &pci_device_fn ) == 0 ) goto __pci_found;          break;	  __pci_found:          pcibios_read_config_dword( pci_bus, pci_device_fn,                                     PCI_BASE_ADDRESS_0, &ioaddr );          ioaddr &= ~3;    /* remove I/O space marker in bit 0. */          if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;          pcibios_read_config_word( pci_bus, pci_device_fn,                                    PCI_COMMAND, &pci_command );          if ( !( pci_command & PCI_COMMAND_IO ) )            {#ifdef HP100_DEBUG              printk( "hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name );#endif              pci_command |= PCI_COMMAND_IO;              pcibios_write_config_word( pci_bus, pci_device_fn,                                         PCI_COMMAND, pci_command );            }          if ( !( pci_command & PCI_COMMAND_MASTER ) )            {#ifdef HP100_DEBUG              printk( "hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name );#endif              pci_command |= PCI_COMMAND_MASTER;              pcibios_write_config_word( pci_bus, pci_device_fn,                                         PCI_COMMAND, pci_command );            }#ifdef HP100_DEBUG          printk( "hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr );#endif	  if ( hp100_probe1( dev, ioaddr, HP100_BUS_PCI, pci_bus, pci_device_fn ) == 0 )	    return 0;        }#endif    }  if ( pci_start_index > 0 ) return -ENODEV;#endif /* CONFIG_PCI */  /* Second: Probe all EISA possible port regions (if EISA bus present) */  for ( ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400 )    {      if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;#ifdef LINUX_2_1      if ( hp100_probe1( dev, ioaddr, HP100_BUS_EISA, NULL ) == 0 ) return 0;#else      if ( hp100_probe1( dev, ioaddr, HP100_BUS_EISA, 0, 0 ) == 0 ) return 0;#endif    }  /* Third Probe all ISA possible port regions */  for ( ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20 )    {      if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;#ifdef LINUX_2_1      if ( hp100_probe1( dev, ioaddr, HP100_BUS_ISA, NULL ) == 0 ) return 0;#else      if ( hp100_probe1( dev, ioaddr, HP100_BUS_ISA, 0, 0 ) == 0 ) return 0;#endif    }  return -ENODEV;}#ifdef LINUX_2_1__initfunc(static int hp100_probe1( struct device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ))#else__initfunc(static int hp100_probe1( struct device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ))#endif{  int i;  u_char uc, uc_1;  u_int eisa_id;  u_int chip;  u_int memory_size = 0, virt_memory_size = 0;  u_short local_mode, lsw;  short mem_mapped;  u_int *mem_ptr_phys, *mem_ptr_virt;  struct hp100_private *lp;  struct hp100_eisa_id *eid;#ifdef HP100_DEBUG_B  hp100_outw( 0x4201, TRACE );  printk("hp100: %s: probe1\n",dev->name);#endif  if ( dev == NULL )    {#ifdef HP100_DEBUG      printk( "hp100_probe1: %s: dev == NULL ?\n", dev->name );#endif      return EIO;    }    if ( hp100_inw( HW_ID ) != HP100_HW_ID_CASCADE )     {      return -ENODEV;    }  else    {      chip = hp100_inw( PAGING ) & HP100_CHIPID_MASK;#ifdef HP100_DEBUG      if ( chip == HP100_CHIPID_SHASTA )        printk("hp100: %s: Shasta Chip detected. (This is a pre 802.12 chip)\n", dev->name);      else if ( chip == HP100_CHIPID_RAINIER )        printk("hp100: %s: Rainier Chip detected. (This is a pre 802.12 chip)\n", dev->name);      else if ( chip == HP100_CHIPID_LASSEN )        printk("hp100: %s: Lassen Chip detected.\n", dev->name);      else        printk("hp100: %s: Warning: Unknown CASCADE chip (id=0x%.4x).\n",dev->name,chip);#endif     }  dev->base_addr = ioaddr;  hp100_page( ID_MAC_ADDR );  for ( i = uc = eisa_id = 0; i < 4; i++ )    {      eisa_id >>= 8;      uc_1 = hp100_inb( BOARD_ID + i );      eisa_id |= uc_1 << 24;      uc += uc_1;    }  uc += hp100_inb( BOARD_ID + 4 );  if ( uc != 0xff )    /* bad checksum? */    {      printk("hp100_probe: %s: bad EISA ID checksum at base port 0x%x\n", dev->name, ioaddr );      return -ENODEV;    }  for ( i=0; i < HP100_EISA_IDS_SIZE; i++)    if ( hp100_eisa_ids[ i ].id == eisa_id )      break;  if ( i >= HP100_EISA_IDS_SIZE ) {    for ( i = 0; i < HP100_EISA_IDS_SIZE; i++)      if ( ( hp100_eisa_ids[ i ].id & 0xf0ffffff ) == ( eisa_id & 0xf0ffffff ) )        break;    if ( i >= HP100_EISA_IDS_SIZE ) {      printk( "hp100_probe: %s: card at port 0x%x isn't known (id = 0x%x)\n", dev -> name, ioaddr, eisa_id );        return -ENODEV;    }  }  eid = &hp100_eisa_ids[ i ];  if ( ( eid->id & 0x0f000000 ) < ( eisa_id & 0x0f000000 ) )    {      printk( "hp100_probe: %s: newer version of card %s at port 0x%x - unsupported\n",	      dev->name, eid->name, ioaddr );      return -ENODEV;    }  for ( i = uc = 0; i < 7; i++ )    uc += hp100_inb( LAN_ADDR + i );  if ( uc != 0xff )    {      printk("hp100_probe: %s: bad lan address checksum (card %s at port 0x%x)\n",	     dev->name, eid->name, ioaddr );      return -EIO;    }  /* Make sure, that all registers are correctly updated... */  hp100_load_eeprom( dev, ioaddr );  wait();  /*   * Determine driver operation mode   *   * Use the variable "hp100_mode" upon insmod or as kernel parameter to   * force driver modes:   * hp100_mode=1 -> default, use busmaster mode if configured.   * hp100_mode=2 -> enable shared memory mode    * hp100_mode=3 -> force use of i/o mapped mode.   * hp100_mode=4 -> same as 1, but re-set the enable bit on the card.   */  /*   * LSW values:   *   0x2278 -> J2585B, PnP shared memory mode   *   0x2270 -> J2585B, shared memory mode, 0xdc000   *   0xa23c -> J2585B, I/O mapped mode   *   0x2240 -> EISA COMPEX, BusMaster (Shasta Chip)   *   0x2220 -> EISA HP, I/O (Shasta Chip)   *   0x2260 -> EISA HP, BusMaster (Shasta Chip)   */#if 0  local_mode = 0x2270;  hp100_outw(0xfefe,OPTION_LSW);  hp100_outw(local_mode|HP100_SET_LB|HP100_SET_HB,OPTION_LSW);#endif  /* hp100_mode value maybe used in future by another card */  local_mode=hp100_mode;  if ( local_mode < 1 || local_mode > 4 )    local_mode = 1;		/* default */#ifdef HP100_DEBUG  printk( "hp100: %s: original LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW) );#endif  if(local_mode==3)    {      hp100_outw(HP100_MEM_EN|HP100_RESET_LB, OPTION_LSW);      hp100_outw(HP100_IO_EN|HP100_SET_LB, OPTION_LSW);      hp100_outw(HP100_BM_WRITE|HP100_BM_READ|HP100_RESET_HB, OPTION_LSW);      printk("hp100: %s: IO mapped mode forced.\n", dev->name);    }  else if(local_mode==2)    {      hp100_outw(HP100_MEM_EN|HP100_SET_LB, OPTION_LSW);      hp100_outw(HP100_IO_EN |HP100_SET_LB, OPTION_LSW);      hp100_outw(HP100_BM_WRITE|HP100_BM_READ|HP100_RESET_HB, OPTION_LSW);      printk("hp100: %s: Shared memory mode requested.\n", dev->name);    }   else if(local_mode==4)    {      if(chip==HP100_CHIPID_LASSEN)	{	  hp100_outw(HP100_BM_WRITE|		     HP100_BM_READ | HP100_SET_HB, OPTION_LSW);	  hp100_outw(HP100_IO_EN   | 		     HP100_MEM_EN  | HP100_RESET_LB, OPTION_LSW);	  printk("hp100: %s: Busmaster mode requested.\n",dev->name);	}      local_mode=1;    }		  if(local_mode==1) /* default behaviour */    {      lsw = hp100_inw(OPTION_LSW);          if ( (lsw & HP100_IO_EN) &&	   (~lsw & HP100_MEM_EN) &&	   (~lsw & (HP100_BM_WRITE|HP100_BM_READ)) )	{#ifdef HP100_DEBUG	  printk("hp100: %s: IO_EN bit is set on card.\n",dev->name);#endif	  local_mode=3;	}      else if ( chip == HP100_CHIPID_LASSEN &&	        ( lsw & (HP100_BM_WRITE|HP100_BM_READ) ) ==	                (HP100_BM_WRITE|HP100_BM_READ) )	{	  printk("hp100: %s: Busmaster mode enabled.\n",dev->name);	  hp100_outw(HP100_MEM_EN|HP100_IO_EN|HP100_RESET_LB, OPTION_LSW);	}      else	{#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);#endif	  /* In this case, try shared memory mode */	  local_mode=2;	  hp100_outw(HP100_MEM_EN|HP100_SET_LB, OPTION_LSW);	  /* hp100_outw(HP100_IO_EN|HP100_RESET_LB, OPTION_LSW); */	}    }#ifdef HP100_DEBUG  printk( "hp100: %s: new LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW) );#endif  /* Check for shared memory on the card, eventually remap it */  hp100_page( HW_MAP );  mem_mapped = (( hp100_inw( OPTION_LSW ) & ( HP100_MEM_EN ) ) != 0);  mem_ptr_phys = mem_ptr_virt = NULL;  memory_size = (8192<<( (hp100_inb(SRAM)>>5)&0x07));  virt_memory_size = 0;  /* For memory mapped or busmaster mode, we want the memory address */  if ( mem_mapped || (local_mode==1))    {      mem_ptr_phys = (u_int *)( hp100_inw( MEM_MAP_LSW ) | 				( hp100_inw( MEM_MAP_MSW ) << 16 ) );      (u_int)mem_ptr_phys &= ~0x1fff;  /* 8k alignment */      if ( bus == HP100_BUS_ISA && ( (u_long)mem_ptr_phys & ~0xfffff ) != 0 )        {	  printk("hp100: %s: Can only use programmed i/o mode.\n", dev->name);          mem_ptr_phys = NULL;          mem_mapped = 0;	  local_mode=3; /* Use programmed i/o */        }						      /* We do not need access to shared memory in busmaster mode */      /* However in slave mode we need to remap high (>1GB) card memory  */      if(local_mode!=1) /* = not busmaster */	{	  if ( bus == HP100_BUS_PCI && mem_ptr_phys >= (u_int *)0x100000 )	    {	      /* We try with smaller memory sizes, if ioremap fails */	      for(virt_memory_size = memory_size; virt_memory_size>16383; virt_memory_size>>=1)		{		  if((mem_ptr_virt=ioremap((u_long)mem_ptr_phys,virt_memory_size))==NULL)		    {#ifdef HP100_DEBUG		      printk( "hp100: %s: ioremap for 0x%x bytes high PCI memory at 0x%lx failed\n", dev->name, virt_memory_size, (u_long)mem_ptr_phys );#endif		    }			  else		    {#ifdef HP100_DEBUG		      printk( "hp100: %s: remapped 0x%x bytes high PCI memory at 0x%lx to 0x%lx.\n", dev->name, virt_memory_size, (u_long)mem_ptr_phys, (u_long)mem_ptr_virt);#endif		      break;		    }		}															      if(mem_ptr_virt==NULL) /* all ioremap tries failed */		{		  printk("hp100: %s: Failed to ioremap the PCI card memory. Will have to use i/o mapped mode.\n", dev->name);		  local_mode=3;		  virt_memory_size = 0;		}	    }	}						    }  if(local_mode==3) /* io mapped forced */    {      mem_mapped = 0;      mem_ptr_phys = mem_ptr_virt = NULL;      printk("hp100: %s: Using (slow) programmed i/o mode.\n", dev->name);    }  /* Initialise the "private" data structure for this card. */  if ( (dev->priv=kmalloc(sizeof(struct hp100_private), GFP_KERNEL)) == NULL)    return -ENOMEM;  lp = (struct hp100_private *)dev->priv;  memset( lp, 0, sizeof( struct hp100_private ) );  lp->id = eid;  lp->chip = chip;  lp->mode = local_mode;  lp->bus = bus;#ifdef LINUX_2_1  lp->pci_dev = pci_dev;#else  lp->pci_bus = pci_bus;  lp->pci_device_fn = pci_device_fn;#endif  lp->priority_tx = hp100_priority_tx;  lp->rx_ratio = hp100_rx_ratio;  lp->mem_ptr_phys = mem_ptr_phys;  lp->mem_ptr_virt = mem_ptr_virt;  hp100_page( ID_MAC_ADDR );  lp->soft_model = hp100_inb( SOFT_MODEL );  lp->mac1_mode = HP100_MAC1MODE3;  lp->mac2_mode = HP100_MAC2MODE3;  memset( &lp->hash_bytes, 0x00, 8 );  dev->base_addr = ioaddr;  lp->memory_size = memory_size;  lp->virt_memory_size = virt_memory_size;  lp->rx_ratio = hp100_rx_ratio; /* can be conf'd with insmod */  /* memory region for programmed i/o */  request_region( dev->base_addr, HP100_REGION_SIZE, eid->name );  dev->open = hp100_open;  dev->stop = hp100_close;  if (lp->mode==1) /* busmaster */    dev->hard_start_xmit = hp100_start_xmit_bm;  else    dev->hard_start_xmit = hp100_start_xmit;  dev->get_stats = hp100_get_stats;  dev->set_multicast_list = &hp100_set_multicast_list;  /* Ask the card for which IRQ line it is configured */#ifdef LINUX_2_1  if ( bus == HP100_BUS_PCI ) {    dev->irq = pci_dev->irq;  } else {#endif    hp100_page( HW_MAP );    dev->irq = hp100_inb( IRQ_CHANNEL ) & HP100_IRQMASK;

⌨️ 快捷键说明

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