ibmmca.c

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

C
1,680
字号
	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(KERN_INFO "IBM MCA SCSI: Separate bus mode (wide-addressing enabled)\n");			subsystem_maxid(host_index) = 16;		} else {			printk(KERN_INFO "IBM MCA SCSI: Combined bus mode (wide-addressing disabled)\n");			subsystem_maxid(host_index) = 8;		}		printk(KERN_INFO "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(KERN_INFO "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(KERN_INFO "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));	if (*buf == TYPE_ROM) {

⌨️ 快捷键说明

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