📄 sym53c8xx_comm.h
字号:
while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { ++pc; ++i; if (!strncmp(p, cur, pc - cur)) return i; cur = pc; } return 0;}static int __init sym53c8xx__setup(char *str){#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT char *cur = str; char *pc, *pv; int i, val, c; int xi = 0; while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { char *pe; val = 0; pv = pc; c = *++pv; if (c == 'n') val = 0; else if (c == 'y') val = 1; else val = (int) simple_strtoul(pv, &pe, 0); switch (get_setup_token(cur)) { case OPT_TAGS: driver_setup.default_tags = val; if (pe && *pe == '/') { i = 0; while (*pe && *pe != ARG_SEP && i < sizeof(driver_setup.tag_ctrl)-1) { driver_setup.tag_ctrl[i++] = *pe++; } driver_setup.tag_ctrl[i] = '\0'; } break; case OPT_MASTER_PARITY: driver_setup.master_parity = val; break; case OPT_SCSI_PARITY: driver_setup.scsi_parity = val; break; case OPT_DISCONNECTION: driver_setup.disconnection = val; break; case OPT_SPECIAL_FEATURES: driver_setup.special_features = val; break; case OPT_ULTRA_SCSI: driver_setup.ultra_scsi = val; break; case OPT_FORCE_SYNC_NEGO: driver_setup.force_sync_nego = val; break; case OPT_REVERSE_PROBE: driver_setup.reverse_probe = val; break; case OPT_DEFAULT_SYNC: driver_setup.default_sync = val; break; case OPT_VERBOSE: driver_setup.verbose = val; break; case OPT_DEBUG: driver_setup.debug = val; break; case OPT_BURST_MAX: driver_setup.burst_max = val; break; case OPT_LED_PIN: driver_setup.led_pin = val; break; case OPT_MAX_WIDE: driver_setup.max_wide = val? 1:0; break; case OPT_SETTLE_DELAY: driver_setup.settle_delay = val; break; case OPT_DIFF_SUPPORT: driver_setup.diff_support = val; break; case OPT_IRQM: driver_setup.irqm = val; break; case OPT_PCI_FIX_UP: driver_setup.pci_fix_up = val; break; case OPT_BUS_CHECK: driver_setup.bus_check = val; break; case OPT_OPTIMIZE: driver_setup.optimize = val; break; case OPT_RECOVERY: driver_setup.recovery = val; break; case OPT_USE_NVRAM: driver_setup.use_nvram = val; break; case OPT_SAFE_SETUP: memcpy(&driver_setup, &driver_safe_setup, sizeof(driver_setup)); break; case OPT_EXCLUDE: if (xi < SCSI_NCR_MAX_EXCLUDES) driver_setup.excludes[xi++] = val; break; case OPT_HOST_ID: driver_setup.host_id = val; break;#ifdef SCSI_NCR_IARB_SUPPORT case OPT_IARB: driver_setup.iarb = val; break;#endif default: printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur); break; } if ((cur = strchr(cur, ARG_SEP)) != NULL) ++cur; }#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ return 1;}/*===================================================================**** Get device queue depth from boot command line.****===================================================================*/#define DEF_DEPTH (driver_setup.default_tags)#define ALL_TARGETS -2#define NO_TARGET -1#define ALL_LUNS -2#define NO_LUN -1static int device_queue_depth(int unit, int target, int lun){ int c, h, t, u, v; char *p = driver_setup.tag_ctrl; char *ep; h = -1; t = NO_TARGET; u = NO_LUN; while ((c = *p++) != 0) { v = simple_strtoul(p, &ep, 0); switch(c) { case '/': ++h; t = ALL_TARGETS; u = ALL_LUNS; break; case 't': if (t != target) t = (target == v) ? v : NO_TARGET; u = ALL_LUNS; break; case 'u': if (u != lun) u = (lun == v) ? v : NO_LUN; break; case 'q': if (h == unit && (t == ALL_TARGETS || t == target) && (u == ALL_LUNS || u == lun)) return v; break; case '-': t = ALL_TARGETS; u = ALL_LUNS; break; default: break; } p = ep; } return DEF_DEPTH;}/*===================================================================**** Print out information about driver configuration.****===================================================================*/static void __init ncr_print_driver_setup(void){#define YesNo(y) y ? 'y' : 'n' printk (NAME53C8XX ": setup=disc:%c,specf:%d,ultra:%d,tags:%d,sync:%d," "burst:%d,wide:%c,diff:%d,revprob:%c,buschk:0x%x\n", YesNo(driver_setup.disconnection), driver_setup.special_features, driver_setup.ultra_scsi, driver_setup.default_tags, driver_setup.default_sync, driver_setup.burst_max, YesNo(driver_setup.max_wide), driver_setup.diff_support, YesNo(driver_setup.reverse_probe), driver_setup.bus_check); printk (NAME53C8XX ": setup=mpar:%c,spar:%c,fsn=%c,verb:%d,debug:0x%x," "led:%c,settle:%d,irqm:0x%x,nvram:0x%x,pcifix:0x%x\n", YesNo(driver_setup.master_parity), YesNo(driver_setup.scsi_parity), YesNo(driver_setup.force_sync_nego), driver_setup.verbose, driver_setup.debug, YesNo(driver_setup.led_pin), driver_setup.settle_delay, driver_setup.irqm, driver_setup.use_nvram, driver_setup.pci_fix_up);#undef YesNo}/*===================================================================**** SYM53C8XX devices description table.****===================================================================*/static ncr_chip ncr_chip_table[] __initdata = SCSI_NCR_CHIP_TABLE;#ifdef SCSI_NCR_PQS_PDS_SUPPORT/*===================================================================**** Detect all NCR PQS/PDS boards and keep track of their bus nr.**** The NCR PQS or PDS card is constructed as a DEC bridge** behind which sit a proprietary NCR memory controller and** four or two 53c875s as separate devices. In its usual mode** of operation, the 875s are slaved to the memory controller** for all transfers. We can tell if an 875 is part of a** PQS/PDS or not since if it is, it will be on the same bus** as the memory controller. To operate with the Linux** driver, the memory controller is disabled and the 875s** freed to function independently. The only wrinkle is that** the preset SCSI ID (which may be zero) must be read in from** a special configuration space register of the 875.****===================================================================*/#define SCSI_NCR_MAX_PQS_BUS 16static int pqs_bus[SCSI_NCR_MAX_PQS_BUS] __initdata = { 0 };static void __init ncr_detect_pqs_pds(void){ short index; pcidev_t dev = PCIDEV_NULL; for(index=0; index < SCSI_NCR_MAX_PQS_BUS; index++) { u_char tmp; dev = pci_find_device(0x101a, 0x0009, dev); if (dev == PCIDEV_NULL) { pqs_bus[index] = -1; break; } printk(KERN_INFO NAME53C8XX ": NCR PQS/PDS memory controller detected on bus %d\n", PciBusNumber(dev)); pci_read_config_byte(dev, 0x44, &tmp); /* bit 1: allow individual 875 configuration */ tmp |= 0x2; pci_write_config_byte(dev, 0x44, tmp); pci_read_config_byte(dev, 0x45, &tmp); /* bit 2: drive individual 875 interrupts to the bus */ tmp |= 0x4; pci_write_config_byte(dev, 0x45, tmp); pqs_bus[index] = PciBusNumber(dev); }}#endif /* SCSI_NCR_PQS_PDS_SUPPORT *//*===================================================================**** Read and check the PCI configuration for any detected NCR ** boards and save data for attaching after all boards have ** been detected.****===================================================================*/static int __initsym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, ncr_device *device){ u_short vendor_id, device_id, command; u_char cache_line_size, latency_timer; u_char suggested_cache_line_size = 0; u_char pci_fix_up = driver_setup.pci_fix_up; u_char revision; u_int irq; u_long base, base_2, io_port; int i; ncr_chip *chip; printk(KERN_INFO NAME53C8XX ": at PCI bus %d, device %d, function %d\n", PciBusNumber(pdev), (int) (PciDeviceFn(pdev) & 0xf8) >> 3, (int) (PciDeviceFn(pdev) & 7));#ifdef SCSI_NCR_DYNAMIC_DMA_MAPPING if (!pci_dma_supported(pdev, (dma_addr_t) (0xffffffffUL))) { printk(KERN_WARNING NAME53C8XX "32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n"); return -1; }#endif /* ** Read info from the PCI config space. ** pci_read_config_xxx() functions are assumed to be used for ** successfully detected PCI devices. */ vendor_id = PciVendorId(pdev); device_id = PciDeviceId(pdev); irq = PciIrqLine(pdev); i = 0; i = pci_get_base_address(pdev, i, &io_port); i = pci_get_base_address(pdev, i, &base); (void) pci_get_base_address(pdev, i, &base_2); pci_read_config_word(pdev, PCI_COMMAND, &command); pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line_size); pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_timer);#ifdef SCSI_NCR_PQS_PDS_SUPPORT /* ** Match the BUS number for PQS/PDS devices. ** Read the SCSI ID from a special register mapped ** into the configuration space of the individual ** 875s. This register is set up by the PQS bios */ for(i = 0; i < SCSI_NCR_MAX_PQS_BUS && pqs_bus[i] != -1; i++) { u_char tmp; if (pqs_bus[i] == PciBusNumber(pdev)) { pci_read_config_byte(pdev, 0x84, &tmp); device->pqs_pds = 1; device->host_id = tmp; break; } }#endif /* SCSI_NCR_PQS_PDS_SUPPORT */ /* ** If user excludes this chip, donnot initialize it. */ for (i = 0 ; i < SCSI_NCR_MAX_EXCLUDES ; i++) { if (driver_setup.excludes[i] == (io_port & PCI_BASE_ADDRESS_IO_MASK)) return -1; } /* ** Check if the chip is supported */ if ((device_id == PCI_DEVICE_ID_LSI_53C1010) || (device_id == PCI_DEVICE_ID_LSI_53C1010_66)){ printk(NAME53C8XX ": not initializing, device not supported\n"); return -1; } chip = 0; for (i = 0; i < sizeof(ncr_chip_table)/sizeof(ncr_chip_table[0]); i++) { if (device_id != ncr_chip_table[i].device_id) continue; if (revision > ncr_chip_table[i].revision_id) continue; chip = &device->chip; memcpy(chip, &ncr_chip_table[i], sizeof(*chip)); chip->revision_id = revision; break; } /* ** Ignore Symbios chips controlled by SISL RAID controller. ** This controller sets value 0x52414944 at RAM end - 16. */#if defined(__i386__) && !defined(SCSI_NCR_PCI_MEM_NOT_SUPPORTED) if (chip && (base_2 & PCI_BASE_ADDRESS_MEM_MASK)) { unsigned int ram_size, ram_val; u_long ram_ptr; if (chip->features & FE_RAM8K) ram_size = 8192; else ram_size = 4096; ram_ptr = remap_pci_mem(base_2 & PCI_BASE_ADDRESS_MEM_MASK, ram_size); if (ram_ptr) { ram_val = readl_raw(ram_ptr + ram_size - 16); unmap_pci_mem(ram_ptr, ram_size); if (ram_val == 0x52414944) { printk(NAME53C8XX": not initializing, " "driven by SISL RAID controller.\n"); return -1; } } }#endif /* i386 and PCI MEMORY accessible */ if (!chip) { printk(NAME53C8XX ": not initializing, device not supported\n"); return -1; }#ifdef __powerpc__ /* ** Fix-up for power/pc. ** Should not be performed by the driver. */ if ((command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) != (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { printk(NAME53C8XX ": setting%s%s...\n", (command & PCI_COMMAND_IO) ? "" : " PCI_COMMAND_IO", (command & PCI_COMMAND_MEMORY) ? "" : " PCI_COMMAND_MEMORY"); command |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY); pci_write_config_word(pdev, PCI_COMMAND, command); }#if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0) if ( is_prep ) { if (io_port >= 0x10000000) { printk(NAME53C8XX ": reallocating io_port (Wacky IBM)"); io_port = (io_port & 0x00FFFFFF) | 0x01000000; pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, io_port); } if (base >= 0x10000000) { printk(NAME53C8XX ": reallocating base (Wacky IBM)"); base = (base & 0x00FFFFFF) | 0x01000000; pci_write_config_dword(pdev, PCI_BASE_ADDRESS_1, base); } if (base_2 >= 0x10000000) { printk(NAME53C8XX ": reallocating base2 (Wacky IBM)"); base_2 = (base_2 & 0x00FFFFFF) | 0x01000000; pci_write_config_dword(pdev, PCI_BASE_ADDRESS_2, base_2); } }#endif#endif /* __powerpc__ */#if defined(__i386__) && !defined(MODULE) if (!cache_line_size) {#if LINUX_VERSION_CODE < LinuxVersionCode(2,1,75) extern char x86; switch(x86) {#else switch(boot_cpu_data.x86) {#endif case 4: suggested_cache_line_size = 4; break; case 6: case 5: suggested_cache_line_size = 8; break; } }#endif /* __i386__ */ /* ** Check availability of IO space, memory space. ** Enable master capability if not yet. ** ** We shouldn't have to care about the IO region when ** we are using MMIO. But calling check_region() from ** both the ncr53c8xx and the sym53c8xx drivers prevents ** from attaching devices from the both drivers. ** If you have a better idea, let me know. *//* #ifdef NCR_IOMAPPED */#if 1 if (!(command & PCI_COMMAND_IO)) { printk(NAME53C8XX ": I/O base address (0x%lx) disabled.\n", (long) io_port); io_port = 0; }#endif if (!(command & PCI_COMMAND_MEMORY)) { printk(NAME53C8XX ": PCI_COMMAND_MEMORY not set.\n"); base = 0; base_2 = 0; } io_port &= PCI_BASE_ADDRESS_IO_MASK; base &= PCI_BASE_ADDRESS_MEM_MASK; base_2 &= PCI_BASE_ADDRESS_MEM_MASK;/* #ifdef NCR_IOMAPPED */#if 1 if (io_port && check_region (io_port, 128)) { printk(NAME53C8XX ": IO region 0x%lx[0..127] is in use\n", (long) io_port); io_port = 0; } if (!io
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -