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

📄 eata.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            link_suffix = ", sorted";         else            link_suffix = ", unsorted";         }      if (tagged_comm && dev->tagged_supported && TLDEV(dev->type)) {         dev->tagged_queue = 1;         dev->current_tag = 1;         }      if (dev->tagged_supported && TLDEV(dev->type) && dev->tagged_queue)         tag_suffix = ", soft-tagged";      else if (dev->tagged_supported && TLDEV(dev->type))         tag_suffix = ", tagged";      printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",             BN(j), host->host_no, dev->channel, dev->id, dev->lun,             dev->queue_depth, link_suffix, tag_suffix);      }   return;}static inline int wait_on_busy(unsigned long iobase, unsigned int loop) {   while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) {      udelay(1L);      if (--loop == 0) return TRUE;      }   return FALSE;}static inline int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) {   if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP))) return TRUE;   if ((addr = V2DEV(addr))) {      outb((char) (addr >> 24), iobase + REG_LOW);      outb((char) (addr >> 16), iobase + REG_LM);      outb((char) (addr >> 8),  iobase + REG_MID);      outb((char)  addr,        iobase + REG_MSB);      }   outb(cmd, iobase + REG_CMD);   return FALSE;}static inline int read_pio(unsigned long iobase, ushort *start, ushort *end) {   unsigned int loop = MAXLOOP;   ushort *p;   for (p = start; p <= end; p++) {      while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) {         udelay(1L);         if (--loop == 0) return TRUE;         }      loop = MAXLOOP;      *p = inw(iobase);      }   return FALSE;}static inline void tune_pci_port(unsigned long port_base) {#if defined(CONFIG_PCI)   unsigned int addr, k;   struct pci_dev *dev = NULL;   if (!pci_present()) return;   for (k = 0; k < MAX_PCI; k++) {      if (!(dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;      addr = pci_resource_start (dev, 0);      if (pci_enable_device (dev)) continue;#if defined(DEBUG_PCI_DETECT)      printk("%s: tune_pci_port, bus %d, devfn 0x%x, addr 0x%x.\n",             driver_name, dev->bus->number, dev->devfn, addr);#endif      if ((addr & PCI_BASE_ADDRESS_IO_MASK) + PCI_BASE_ADDRESS_0 == port_base) {         pci_set_master(dev);         return;         }      }#endif /* end CONFIG_PCI */   return;}static inline int            get_pci_irq(unsigned long port_base, unsigned char *apic_irq) {#if defined(CONFIG_PCI)   unsigned int addr;   struct pci_dev *dev = NULL;   if (!pci_present()) return FALSE;   while((dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {      if (pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &addr)) continue;#if defined(DEBUG_PCI_DETECT)      printk("%s: get_pci_irq, bus %d, devfn 0x%x, addr 0x%x, apic_irq %u.\n",             driver_name, dev->bus->number, dev->devfn, addr, dev->irq);#endif      if ((addr & PCI_BASE_ADDRESS_IO_MASK) + PCI_BASE_ADDRESS_0 == port_base) {         *apic_irq = dev->irq;         return TRUE;         }      }#endif /* end CONFIG_PCI */   return FALSE;}static inline int port_detect \      (unsigned long port_base, unsigned int j, Scsi_Host_Template *tpnt) {   unsigned char irq, dma_channel, subversion, i;   unsigned char protocol_rev, apic_irq;   struct eata_info info;   char *bus_type, dma_name[16], tag_type;   /* Allowed DMA channels for ISA (0 indicates reserved) */   unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };   char name[16];   sprintf(name, "%s%d", driver_name, j);   if(check_region(port_base, REGION_SIZE)) {#if defined(DEBUG_DETECT)      printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base);#endif      return FALSE;      }   if (do_dma(port_base, 0, READ_CONFIG_PIO)) return FALSE;   /* Read the info structure */   if (read_pio(port_base, (ushort *)&info, (ushort *)&info.ipad[0]))      return FALSE;   /* Check the controller "EATA" signature */   if (info.sign != EATA_SIGNATURE) return FALSE;   if (DEV2H(info.data_len) < EATA_2_0A_SIZE) {      printk("%s: config structure size (%d bytes) too short, detaching.\n",             name, DEV2H(info.data_len));      return FALSE;      }   else if (DEV2H(info.data_len) == EATA_2_0A_SIZE)      protocol_rev = 'A';   else if (DEV2H(info.data_len) == EATA_2_0B_SIZE)      protocol_rev = 'B';   else      protocol_rev = 'C';   if (!setup_done && j > 0 && j <= MAX_PCI) {      bus_type = "PCI";      subversion = ESA;      }   else if (port_base > MAX_EISA_ADDR || (protocol_rev == 'C' && info.pci)) {      bus_type = "PCI";      subversion = ESA;      }   else if (port_base >= MIN_EISA_ADDR || (protocol_rev == 'C' && info.eisa)) {      bus_type = "EISA";      subversion = ESA;      }   else if (protocol_rev == 'C' && !info.eisa && !info.pci) {      bus_type = "ISA";      subversion = ISA;      }   else if (port_base > MAX_ISA_ADDR) {      bus_type = "PCI";      subversion = ESA;      }   else {      bus_type = "ISA";      subversion = ISA;      }   if (!info.haaval || info.ata) {      printk("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n",             name, port_base, bus_type, info.haaval, info.ata);      return FALSE;      }   if (info.drqvld) {      if (subversion ==  ESA)         printk("%s: warning, weird %s board using DMA.\n", name, bus_type);      subversion = ISA;      dma_channel = dma_channel_table[3 - info.drqx];      }   else {      if (subversion ==  ISA)         printk("%s: warning, weird %s board not using DMA.\n", name, bus_type);      subversion = ESA;      dma_channel = NO_DMA;      }   if (!info.dmasup)      printk("%s: warning, DMA protocol support not asserted.\n", name);   irq = info.irq;   if (subversion == ESA && !info.irq_tr)      printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",             name, irq);   if (get_pci_irq(port_base, &apic_irq) && (irq != apic_irq)) {      printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq, apic_irq);      irq = apic_irq;      }   /* Board detected, allocate its IRQ */   if (request_irq(irq, do_interrupt_handler,             SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),             driver_name, (void *) &sha[j])) {      printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);      return FALSE;      }   if (subversion == ISA && request_dma(dma_channel, driver_name)) {      printk("%s: unable to allocate DMA channel %u, detaching.\n",             name, dma_channel);      free_irq(irq, &sha[j]);      return FALSE;      }#if defined(FORCE_CONFIG)   {   struct eata_config config;   /* Set board configuration */   memset((char *)&config, 0, sizeof(struct eata_config));   config.len = (ushort) htons((ushort)510);   config.ocena = TRUE;   if (do_dma(port_base, (unsigned long)&config, SET_CONFIG_DMA)) {      printk("%s: busy timeout sending configuration, detaching.\n", name);      return FALSE;      }   }#endif   sh[j] = scsi_register(tpnt, sizeof(struct hostdata));   if (sh[j] == NULL) {      printk("%s: unable to register host, detaching.\n", name);      free_irq(irq, &sha[j]);      if (subversion == ISA) free_dma(dma_channel);      return FALSE;      }   sh[j]->io_port = port_base;   sh[j]->unique_id = port_base;   sh[j]->n_io_port = REGION_SIZE;   sh[j]->dma_channel = dma_channel;   sh[j]->irq = irq;   sh[j]->sg_tablesize = (ushort) ntohs(info.scatt_size);   sh[j]->this_id = (ushort) info.host_addr[3];   sh[j]->can_queue = (ushort) ntohs(info.queue_size);   sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;   sh[j]->select_queue_depths = select_queue_depths;   /* Register the I/O space that we use */   request_region(sh[j]->io_port, sh[j]->n_io_port, driver_name);   memset(HD(j), 0, sizeof(struct hostdata));   HD(j)->subversion = subversion;   HD(j)->protocol_rev = protocol_rev;   HD(j)->board_number = j;   if (HD(j)->subversion == ESA)      sh[j]->unchecked_isa_dma = FALSE;   else {      unsigned long flags;      scsi_register_blocked_host(sh[j]);      sh[j]->unchecked_isa_dma = TRUE;            flags=claim_dma_lock();      disable_dma(dma_channel);      clear_dma_ff(dma_channel);      set_dma_mode(dma_channel, DMA_MODE_CASCADE);      enable_dma(dma_channel);      release_dma_lock(flags);            }   strcpy(BN(j), name);   /* DPT PM2012 does not allow to detect sg_tablesize correctly */   if (sh[j]->sg_tablesize > MAX_SGLIST || sh[j]->sg_tablesize < 2) {      printk("%s: detect, wrong n. of SG lists %d, fixed.\n",             BN(j), sh[j]->sg_tablesize);      sh[j]->sg_tablesize = MAX_SGLIST;      }   /* DPT PM2012 does not allow to detect can_queue correctly */   if (sh[j]->can_queue > MAX_MAILBOXES || sh[j]->can_queue  < 2) {      printk("%s: detect, wrong n. of mbox %d, fixed.\n",             BN(j), sh[j]->can_queue);      sh[j]->can_queue = MAX_MAILBOXES;      }   if (protocol_rev != 'A') {      if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL)         sh[j]->max_channel = info.max_chan;      if (info.max_id > 7 && info.max_id < MAX_TARGET)         sh[j]->max_id = info.max_id + 1;      if (info.large_sg && sh[j]->sg_tablesize == MAX_SGLIST)         sh[j]->sg_tablesize = MAX_LARGE_SGLIST;      }   if (protocol_rev == 'C') {      if (info.max_lun > 7 && info.max_lun < MAX_LUN)         sh[j]->max_lun = info.max_lun + 1;      }   if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "BMST");   else                       sprintf(dma_name, "DMA %u", dma_channel);   for (i = 0; i < sh[j]->can_queue; i++)      if (! ((&HD(j)->cp[i])->sglist = kmalloc(            sh[j]->sg_tablesize * sizeof(struct sg_list),            (sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) {         printk("%s: kmalloc SGlist failed, mbox %d, detaching.\n", BN(j), i);         eata2x_release(sh[j]);         return FALSE;         }   if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)       max_queue_depth = MAX_TAGGED_CMD_PER_LUN;   if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN;   if (tagged_comm) {      if      (tag_mode == TAG_SIMPLE)  tag_type = '1';      else if (tag_mode == TAG_HEAD)    tag_type = '2';      else if (tag_mode == TAG_ORDERED) tag_type = '3';      else                              tag_type = 'y';      }   else                                 tag_type = 'n';   if (j == 0) {      printk("EATA/DMA 2.0x: Copyright (C) 1994-2000 Dario Ballabio.\n");      printk("%s config options -> tc:%c, lc:%c, mq:%d, rs:%c, et:%c.\n",             driver_name, tag_type, YESNO(linked_comm), max_queue_depth,             YESNO(rev_scan), YESNO(ext_tran));      }

⌨️ 快捷键说明

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