📄 ibmmca.c
字号:
const char hex[16] = "0123456789abcdef"; static char answer[2]; answer[1] = (char)(0x0); if (val<=MAX_LOG_DEV) answer[0] = hex[val]; else answer[0] = '-'; return (char *)&answer;}/* transfers bitpattern of the feature command to values in MHz */static char *ibmrate(unsigned int speed, int i){ switch (speed) { case 0: return i ? "5.00" : "10.00"; case 1: return i ? "4.00" : "8.00"; case 2: return i ? "3.33" : "6.66"; case 3: return i ? "2.86" : "5.00"; case 4: return i ? "2.50" : "4.00"; case 5: return i ? "2.22" : "3.10"; case 6: return i ? "2.00" : "2.50"; case 7: return i ? "1.82" : "2.00"; } return "---";}static int probe_display(int what){ static int rotator = 0; const char rotor[] = "|/-\\"; if (!(display_mode & LED_DISP)) return 0; if (!what) { outl(0x20202020,MOD95_LED_PORT); outl(0x20202020,MOD95_LED_PORT+4); } else { outb('S',MOD95_LED_PORT+7); outb('C',MOD95_LED_PORT+6); outb('S',MOD95_LED_PORT+5); outb('I',MOD95_LED_PORT+4); outb('i',MOD95_LED_PORT+3); outb('n',MOD95_LED_PORT+2); outb('i',MOD95_LED_PORT+1); outb((char)(rotor[rotator]),MOD95_LED_PORT); rotator++; if (rotator>3) rotator=0; } return 0;}static int probe_bus_mode(int host_index){ struct im_pos_info *info; int num_bus = 0; int ldn; info = (struct im_pos_info *)(&(ld(host_index)[MAX_LOG_DEV].buf)); if (get_pos_info(host_index)) { if (info->connector_size & 0xf000) subsystem_connector_size(host_index)=16; else subsystem_connector_size(host_index)=32; num_bus |= (info->pos_4b & 8) >> 3; for (ldn=0; ldn<=MAX_LOG_DEV; ldn++) { if ((special(host_index)==IBM_SCSI_WCACHE)|| (special(host_index)==IBM_7568_WCACHE)) { if (!((info->cache_stat >> ldn) & 1)) ld(host_index)[ldn].cache_flag = 0; } if (!((info->retry_stat >> ldn) & 1)) ld(host_index)[ldn].retry_flag = 0; }#ifdef IM_DEBUG_PROBE printk("IBM MCA SCSI: SCSI-Cache bits: "); for (ldn=0; ldn<=MAX_LOG_DEV; ldn++) { printk("%d",ld(host_index)[ldn].cache_flag); } printk("\nIBM MCA SCSI: SCSI-Retry bits: "); for (ldn=0; ldn<=MAX_LOG_DEV; ldn++) { printk("%d",ld(host_index)[ldn].retry_flag); } printk("\n");#endif } return num_bus;}/* probing scsi devices */static void check_devices (int host_index, int adaptertype){ int id, lun, ldn, ticks; int count_devices; /* local counter for connected device */ int max_pun; int num_bus; int speedrun; /* local adapter_speed check variable */ /* assign default values to certain variables */ ticks = 0; count_devices = 0; IBM_DS(host_index).dyn_flag = 0; /* normally no need for dynamical ldn management */ IBM_DS(host_index).total_errors = 0; /* set errorcounter to 0 */ next_ldn(host_index) = 7; /* next ldn to be assigned is 7, because 0-6 is 'hardwired'*/ /* initialize the very important driver-informational arrays/structs */ memset (ld(host_index), 0, sizeof(ld(host_index))); for (ldn=0; ldn<=MAX_LOG_DEV; ldn++) { last_scsi_command(host_index)[ldn] = NO_SCSI; /* emptify last SCSI-command storage */ last_scsi_type(host_index)[ldn] = 0; ld(host_index)[ldn].cache_flag = 1; ld(host_index)[ldn].retry_flag = 1; } memset (get_ldn(host_index), TYPE_NO_DEVICE, sizeof(get_ldn(host_index))); /* this is essential ! */ memset (get_scsi(host_index), TYPE_NO_DEVICE, sizeof(get_scsi(host_index))); /* this is essential ! */ for (lun=0; lun<8; lun++) { /* mark the adapter at its pun on all luns*/ get_scsi(host_index)[subsystem_pun(host_index)][lun] = TYPE_IBM_SCSI_ADAPTER; get_ldn(host_index)[subsystem_pun(host_index)][lun] = MAX_LOG_DEV; /* make sure, the subsystem ldn is active for all luns. */ } probe_display(0); /* Supercool display usage during SCSI-probing. */ /* This makes sense, when booting without any */ /* monitor connected on model XX95. */ /* STEP 1: */ adapter_speed(host_index) = global_adapter_speed; speedrun = adapter_speed(host_index); while (immediate_feature(host_index,speedrun,adapter_timeout)==2) { probe_display(1); if (speedrun==7) panic("IBM MCA SCSI: Cannot set Synchronous-Transfer-Rate!\n"); speedrun++; if (speedrun>7) speedrun=7; } adapter_speed(host_index) = speedrun; /* Get detailed information about the current adapter, necessary for * device operations: */ num_bus=probe_bus_mode(host_index); /* num_bus contains only valid data for the F/W adapter! */ if (adaptertype==IBM_SCSI2_FW) { /* F/W SCSI adapter: */ /* F/W adapter PUN-space extension evaluation: */ if (num_bus) { printk("IBM MCA SCSI: Seperate bus mode (wide-addressing enabled)\n"); subsystem_maxid(host_index) = 16; } else { printk("IBM MCA SCSI: Combined bus mode (wide-addressing disabled)\n"); subsystem_maxid(host_index) = 8; } printk("IBM MCA SCSI: Sync.-Rate (F/W: 20, Int.: 10, Ext.: %s) MBytes/s\n", ibmrate(speedrun,adaptertype)); } else /* all other IBM SCSI adapters: */ printk("IBM MCA SCSI: Synchronous-SCSI-Transfer-Rate: %s MBytes/s\n", ibmrate(speedrun,adaptertype)); /* assign correct PUN device space */ max_pun = subsystem_maxid(host_index);#ifdef IM_DEBUG_PROBE printk("IBM MCA SCSI: Current SCSI-host index: %d\n",host_index); printk("IBM MCA SCSI: Removing default logical SCSI-device mapping.");#else printk("IBM MCA SCSI: Dev. Order: %s, Mapping (takes <2min): ", (ibm_ansi_order) ? "ANSI" : "New");#endif for (ldn=0; ldn<MAX_LOG_DEV; ldn++) { probe_display(1);#ifdef IM_DEBUG_PROBE printk(".");#endif immediate_assign(host_index,0,0,ldn,REMOVE_LDN); /* remove ldn (wherever)*/ } lun = 0; /* default lun is 0 */#ifndef IM_DEBUG_PROBE printk("cleared,");#endif /* STEP 2: */#ifdef IM_DEBUG_PROBE printk("\nIBM MCA SCSI: Scanning SCSI-devices.");#endif for (id=0; id<max_pun ; id++)#ifdef CONFIG_SCSI_MULTI_LUN for (lun=0; lun<8; lun++)#endif { probe_display(1);#ifdef IM_DEBUG_PROBE printk(".");#endif if (id != subsystem_pun(host_index)) { /* if pun is not the adapter: */ /* set ldn=0 to pun,lun*/ immediate_assign(host_index,id,lun,PROBE_LDN,SET_LDN); if (device_inquiry(host_index, PROBE_LDN)) { /* probe device */ get_scsi(host_index)[id][lun]= (unsigned char)(ld(host_index)[PROBE_LDN].buf[0]); /* entry, even for NO_LUN */ if (ld(host_index)[PROBE_LDN].buf[0] != TYPE_NO_LUN) count_devices++; /* a existing device is found */ } /* remove ldn */ immediate_assign(host_index,id,lun,PROBE_LDN,REMOVE_LDN); } }#ifndef IM_DEBUG_PROBE printk("scanned,");#endif /* STEP 3: */#ifdef IM_DEBUG_PROBE printk("\nIBM MCA SCSI: Mapping SCSI-devices.");#endif ldn = 0; lun = 0;#ifdef CONFIG_SCSI_MULTI_LUN for (lun=0; lun<8 && ldn<MAX_LOG_DEV; lun++)#endif for (id=0; id<max_pun && ldn<MAX_LOG_DEV; id++) { probe_display(1);#ifdef IM_DEBUG_PROBE printk(".");#endif if (id != subsystem_pun(host_index)) { if (get_scsi(host_index)[id][lun] != TYPE_NO_LUN && get_scsi(host_index)[id][lun] != TYPE_NO_DEVICE) { /* Only map if accepted type. Always enter for lun == 0 to get no gaps into ldn-mapping for ldn<7. */ immediate_assign(host_index,id,lun,ldn,SET_LDN); get_ldn(host_index)[id][lun]=ldn; /* map ldn */ if (device_exists (host_index, ldn, &ld(host_index)[ldn].block_length, &ld(host_index)[ldn].device_type)) {#ifdef CONFIG_IBMMCA_SCSI_DEV_RESET printk("resetting device at ldn=%x ... ",ldn); immediate_reset(host_index,ldn);#endif ldn++; } else { /* device vanished, probably because we don't know how to * handle it or because it has problems */ if (lun > 0) { /* remove mapping */ get_ldn(host_index)[id][lun]=TYPE_NO_DEVICE; immediate_assign(host_index,0,0,ldn,REMOVE_LDN); } else ldn++; } } else if (lun == 0) { /* map lun == 0, even if no device exists */ immediate_assign(host_index,id,lun,ldn,SET_LDN); get_ldn(host_index)[id][lun]=ldn; /* map ldn */ ldn++; } } } /* STEP 4: */ /* map remaining ldns to non-existing devices */ for (lun=1; lun<8 && ldn<MAX_LOG_DEV; lun++) for (id=0; id<max_pun && ldn<MAX_LOG_DEV; id++) { if (get_scsi(host_index)[id][lun] == TYPE_NO_LUN || get_scsi(host_index)[id][lun] == TYPE_NO_DEVICE) { probe_display(1); /* Map remaining ldns only to NON-existing pun,lun combinations to make sure an inquiry will fail. For MULTI_LUN, it is needed to avoid adapter autonome SCSI-remapping. */ immediate_assign(host_index,id,lun,ldn,SET_LDN); get_ldn(host_index)[id][lun]=ldn; ldn++; } }#ifndef IM_DEBUG_PROBE printk("mapped.");#endif printk("\n");#ifdef IM_DEBUG_PROBE if (ibm_ansi_order) printk("IBM MCA SCSI: Device order: IBM/ANSI (pun=7 is first).\n"); else printk("IBM MCA SCSI: Device order: New Industry Standard (pun=0 is first).\n");#endif#ifdef IM_DEBUG_PROBE /* Show the physical and logical mapping during boot. */ printk("IBM MCA SCSI: Determined SCSI-device-mapping:\n"); printk(" Physical SCSI-Device Map Logical SCSI-Device Map\n"); printk("ID\\LUN 0 1 2 3 4 5 6 7 ID\\LUN 0 1 2 3 4 5 6 7\n"); for (id=0; id<max_pun; id++) { printk("%2d ",id); for (lun=0; lun<8; lun++) printk("%2s ",ti_p(get_scsi(host_index)[id][lun])); printk(" %2d ",id); for (lun=0; lun<8; lun++) printk("%2s ",ti_l(get_ldn(host_index)[id][lun])); printk("\n"); }#endif /* assign total number of found SCSI-devices to the statistics struct */ IBM_DS(host_index).total_scsi_devices = count_devices; /* decide for output in /proc-filesystem, if the configuration of SCSI-devices makes dynamical reassignment of devices necessary */ if (count_devices>=MAX_LOG_DEV) IBM_DS(host_index).dyn_flag = 1; /* dynamical assignment is necessary */ else IBM_DS(host_index).dyn_flag = 0; /* dynamical assignment is not necessary */ /* If no SCSI-devices are assigned, return 1 in order to cause message. */ if (ldn == 0) printk("IBM MCA SCSI: Warning: No SCSI-devices found/assigned!\n"); /* reset the counters for statistics on the current adapter */ IBM_DS(host_index).scbs = 0; IBM_DS(host_index).long_scbs = 0; IBM_DS(host_index).total_accesses = 0; IBM_DS(host_index).total_interrupts = 0; IBM_DS(host_index).dynamical_assignments = 0; memset (IBM_DS(host_index).ldn_access, 0x0, sizeof (IBM_DS(host_index).ldn_access)); memset (IBM_DS(host_index).ldn_read_access, 0x0, sizeof (IBM_DS(host_index).ldn_read_access)); memset (IBM_DS(host_index).ldn_write_access, 0x0, sizeof (IBM_DS(host_index).ldn_write_access)); memset (IBM_DS(host_index).ldn_inquiry_access, 0x0, sizeof (IBM_DS(host_index).ldn_inquiry_access)); memset (IBM_DS(host_index).ldn_modeselect_access, 0x0, sizeof (IBM_DS(host_index).ldn_modeselect_access)); memset (IBM_DS(host_index).ldn_assignments, 0x0, sizeof (IBM_DS(host_index).ldn_assignments)); probe_display(0); return;}static int device_exists (int host_index, int ldn, int *block_length, int *device_type){ unsigned char *buf; /* if no valid device found, return immediately with 0 */ if (!(device_inquiry(host_index, ldn))) return 0; buf = (unsigned char *)(&(ld(host_index)[ldn].buf));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -