eata.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,842 行 · 第 1/5 页

C
1,842
字号
      protocol_rev = 'B';   else      protocol_rev = 'C';   if (protocol_rev != 'A' && info.forcaddr) {      printk("%s: warning, port address has been forced.\n", name);      bus_type = "PCI";      is_pci = TRUE;      subversion = ESA;      }   else if (port_base > MAX_EISA_ADDR || (protocol_rev == 'C' && info.pci)) {      bus_type = "PCI";      is_pci = TRUE;      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";      is_pci = TRUE;      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);      goto freelock;      }   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 (is_pci) {      pdev = get_pci_dev(port_base);      if (!pdev)         printk("%s: warning, failed to get pci_dev structure.\n", name);      }   else      pdev = NULL;   if (pdev && (irq != pdev->irq)) {      printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq, pdev->irq);      irq = pdev->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);      goto freelock;      }   if (subversion == ISA && request_dma(dma_channel, driver_name)) {      printk("%s: unable to allocate DMA channel %u, detaching.\n",             name, dma_channel);      goto freeirq;      }#if defined(FORCE_CONFIG)   {   struct eata_config *cf;   dma_addr_t cf_dma_addr;   cf = pci_alloc_consistent(pdev, sizeof(struct eata_config), &cf_dma_addr);   if (!cf) {      printk("%s: config, pci_alloc_consistent failed, detaching.\n", name);      goto freedma;      }   /* Set board configuration */   memset((char *)cf, 0, sizeof(struct eata_config));   cf->len = (ushort) H2DEV16((ushort)510);   cf->ocena = TRUE;   if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) {      printk("%s: busy timeout sending configuration, detaching.\n", name);      pci_free_consistent(pdev, sizeof(struct eata_config), cf, cf_dma_addr);      goto freedma;      }   }#endif   spin_unlock_irq(&driver_lock);   sh[j] = scsi_register(tpnt, sizeof(struct hostdata));   spin_lock_irq(&driver_lock);   if (sh[j] == NULL) {      printk("%s: unable to register host, detaching.\n", name);      goto freedma;      }   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) info.scatt_size;   sh[j]->this_id = (ushort) info.host_addr[3];   sh[j]->can_queue = (ushort) info.queue_size;   sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;   memset(HD(j), 0, sizeof(struct hostdata));   HD(j)->subversion = subversion;   HD(j)->protocol_rev = protocol_rev;   HD(j)->is_pci = is_pci;   HD(j)->pdev = pdev;   HD(j)->board_number = j;   if (HD(j)->subversion == ESA)      sh[j]->unchecked_isa_dma = FALSE;   else {      unsigned long flags;      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);   spin_unlock_irq(&driver_lock);   for (i = 0; i < sh[j]->can_queue; i++)      HD(j)->cp[i].cp_dma_addr = pci_map_single(HD(j)->pdev,            &HD(j)->cp[i], sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);   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);         goto release;         }   if (! (HD(j)->sp_cpu_addr = pci_alloc_consistent(HD(j)->pdev,         sizeof(struct mssp), &HD(j)->sp_dma_addr))) {      printk("%s: pci_alloc_consistent failed, detaching.\n", BN(j));      goto release;      }   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 (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE)      tag_mode = TAG_ORDERED;   if (j == 0) {      printk("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n");      printk("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, "\             "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode,             YESNO(linked_comm), max_queue_depth, YESNO(rev_scan),             YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe),             YESNO(pci_probe));      }   printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n",          BN(j), HD(j)->protocol_rev, bus_type, (unsigned long)sh[j]->io_port,          sh[j]->irq, dma_name, sh[j]->sg_tablesize, sh[j]->can_queue);   if (sh[j]->max_id > 8 || sh[j]->max_lun > 8)      printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",             BN(j), sh[j]->max_id, sh[j]->max_lun);   for (i = 0; i <= sh[j]->max_channel; i++)      printk("%s: SCSI channel %u enabled, host target ID %d.\n",             BN(j), i, info.host_addr[3 - i]);#if defined(DEBUG_DETECT)   printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, "\          "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version,          info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync,          info.second, info.data_len, info.cp_len,          info.sp_len);   if (protocol_rev == 'B' || protocol_rev == 'C')      printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, "\             "large_sg %u, res1 %u.\n", name, info.isaena, info.forcaddr,             info.max_id, info.max_chan, info.large_sg, info.res1);   if (protocol_rev == 'C')      printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, "\             "raidnum %u.\n", name, info.max_lun, info.m1, info.idquest,             info.pci, info.eisa, info.raidnum);#endif   if (HD(j)->pdev) {      pci_set_master(HD(j)->pdev);      if (pci_set_dma_mask(HD(j)->pdev, 0xffffffff))         printk("%s: warning, pci_set_dma_mask failed.\n", BN(j));      }   return TRUE;freedma:   if (subversion == ISA) free_dma(dma_channel);freeirq:   free_irq(irq, &sha[j]);freelock:   spin_unlock_irq(&driver_lock);   release_region(port_base, REGION_SIZE);fail:   return FALSE;release:   eata2x_release(sh[j]);   return FALSE;}static void internal_setup(char *str, int *ints) {   int i, argc = ints[0];   char *cur = str, *pc;   if (argc > 0) {      if (argc > MAX_INT_PARAM) argc = MAX_INT_PARAM;      for (i = 0; i < argc; i++) io_port[i] = ints[i + 1];      io_port[i] = 0;      setup_done = TRUE;      }   while (cur && (pc = strchr(cur, ':'))) {      int val = 0, c = *++pc;      if (c == 'n' || c == 'N') val = FALSE;      else if (c == 'y' || c == 'Y') val = TRUE;      else val = (int) simple_strtoul(pc, NULL, 0);      if (!strncmp(cur, "lc:", 3)) linked_comm = val;      else if (!strncmp(cur, "tm:", 3)) tag_mode = val;      else if (!strncmp(cur, "tc:", 3)) tag_mode = val;      else if (!strncmp(cur, "mq:", 3))  max_queue_depth = val;      else if (!strncmp(cur, "ls:", 3))  link_statistics = val;      else if (!strncmp(cur, "et:", 3))  ext_tran = val;      else if (!strncmp(cur, "rs:", 3))  rev_scan = val;      else if (!strncmp(cur, "ip:", 3))  isa_probe = val;      else if (!strncmp(cur, "ep:", 3))  eisa_probe = val;      else if (!strncmp(cur, "pp:", 3))  pci_probe = val;      if ((cur = strchr(cur, ','))) ++cur;      }   return;}static int option_setup(char *str) {   int ints[MAX_INT_PARAM];   char *cur = str;   int i = 1;   while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) {      ints[i++] = simple_strtoul(cur, NULL, 0);      if ((cur = strchr(cur, ',')) != NULL) cur++;   }   ints[0] = i - 1;   internal_setup(cur, ints);   return 1;}static void add_pci_ports(void) {#if defined(CONFIG_PCI)   unsigned int addr, k;   struct pci_dev *dev = NULL;   for (k = 0; k < MAX_PCI; k++) {      if (!(dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;      if (pci_enable_device (dev)) {#if defined(DEBUG_PCI_DETECT)         printk("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n",                driver_name, dev->bus->number, dev->devfn);#endif         continue;         }      addr = pci_resource_start (dev, 0);#if defined(DEBUG_PCI_DETECT)      printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",             driver_name, k, dev->bus->number, dev->devfn, addr);#endif      /* Order addresses according to rev_scan value */

⌨️ 快捷键说明

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