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

📄 ibmmca.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
   if (*buf == TYPE_ROM) {      *device_type = TYPE_ROM;      *block_length = 2048; /* (standard blocksize for yellow-/red-book) */      return 1;   }   if (*buf == TYPE_WORM) {      *device_type = TYPE_WORM;      *block_length = 2048;      return 1;   }   if (*buf == TYPE_DISK) {      *device_type = TYPE_DISK;      if (read_capacity( host_index, ldn)) {	 *block_length = *(buf+7) + (*(buf+6) << 8) +	   (*(buf+5) << 16) + (*(buf+4) << 24);	 return 1;      } else	return 0;   }   if (*buf == TYPE_MOD) {      *device_type = TYPE_MOD;      if (read_capacity( host_index, ldn)) {	 *block_length = *(buf+7) + (*(buf+6) << 8) +	   (*(buf+5) << 16) + (*(buf+4) << 24);	 return 1;      } else	return 0;   }   if (*buf == TYPE_TAPE) {      *device_type = TYPE_TAPE;      *block_length = 0; /* not in use (setting by mt and mtst in op.) */      return 1;   }   if (*buf == TYPE_PROCESSOR) {      *device_type = TYPE_PROCESSOR;      *block_length = 0; /* they set their stuff on drivers */      return 1;   }   if (*buf == TYPE_SCANNER) {      *device_type = TYPE_SCANNER;      *block_length = 0; /* they set their stuff on drivers */      return 1;   }   if (*buf == TYPE_MEDIUM_CHANGER) {      *device_type = TYPE_MEDIUM_CHANGER;      *block_length = 0; /* One never knows, what to expect on a medium			    changer device. */      return 1;   }   return 0;}void internal_ibmmca_scsi_setup (char *str, int *ints){   int i, j, io_base, id_base;   char *token;   io_base = 0;   id_base = 0;   if (str) {      token = strtok(str,",");      j = 0;      while (token) {	 if (!strcmp(token,"activity")) display_mode |= LED_ACTIVITY;	 if (!strcmp(token,"display")) display_mode |= LED_DISP;	 if (!strcmp(token,"adisplay")) display_mode |= LED_ADISP;	 if (!strcmp(token,"normal")) ibm_ansi_order = 0;	 if (!strcmp(token,"ansi")) ibm_ansi_order = 1;	 if (!strcmp(token,"fast")) global_adapter_speed = 0;	 if (!strcmp(token,"medium")) global_adapter_speed = 4;	 if (!strcmp(token,"slow")) global_adapter_speed = 7;	 if ((*token == '-') || (isdigit(*token))) {	    if (!(j%2) && (io_base < IM_MAX_HOSTS))	      io_port[io_base++] = simple_strtoul(token,NULL,0);	    if ((j%2) && (id_base < IM_MAX_HOSTS))	      scsi_id[id_base++] = simple_strtoul(token,NULL,0);	    j++;	 }	 token = strtok(NULL,",");      }   } else if (ints) {      for (i = 0; i < IM_MAX_HOSTS && 2*i+2 < ints[0]; i++) {	 io_port[i] = ints[2*i+2];	 scsi_id[i] = ints[2*i+2];      }   }   return;}static int ibmmca_getinfo (char *buf, int slot, void *dev){   struct Scsi_Host *shpnt;   int len, speciale, connectore, k;   unsigned int pos[8];   unsigned long flags;   IBMLOCK   shpnt = dev; /* assign host-structure to local pointer */   len = 0; /* set filled text-buffer index to 0 */   /* get the _special contents of the hostdata structure */   speciale = ((struct ibmmca_hostdata *)shpnt->hostdata)->_special;   connectore = ((struct ibmmca_hostdata *)shpnt->hostdata)->_connector_size;   for (k=2;k<4;k++)     pos[k] = ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos[k];   if (speciale == FORCED_DETECTION) { /* forced detection */      len += sprintf (buf+len,		      "Adapter category: forced detected\n"		      "***************************************\n"		      "***  Forced detected SCSI Adapter   ***\n"		      "***  No chip-information available  ***\n"		      "***************************************\n");   } else if (speciale == INTEGRATED_SCSI) {      /* if the integrated subsystem has been found automatically: */      len += sprintf (buf+len,		      "Adapter category: integrated\n"		      "Chip revision level: %d\n"		      "Chip status: %s\n"		      "8 kByte NVRAM status: %s\n",		      ((pos[2] & 0xf0) >> 4),		      (pos[2] & 1) ? "enabled" : "disabled",		      (pos[2] & 2) ? "locked" : "accessible");   } else if ((speciale>=0)&&	      (speciale<(sizeof(subsys_list)/sizeof(struct subsys_list_struct)))) {      /* if the subsystem is a slot adapter */      len += sprintf (buf+len,		      "Adapter category: slot-card\n"		      "ROM Segment Address: ");      if ((pos[2] & 0xf0) == 0xf0)	len += sprintf (buf+len, "off\n");      else	len += sprintf (buf+len, "0x%x\n",			((pos[2] & 0xf0) << 13) + 0xc0000);      len += sprintf (buf + len, "Chip status: %s\n",		      (pos[2] & 1) ? "enabled" : "disabled");      len += sprintf (buf + len, "Adapter I/O Offset: 0x%x\n",		      ((pos[2] & 0x0e) << 2));   } else {      len += sprintf (buf + len, "Adapter category: unknown\n");   }   /* common subsystem information to write to the slotn file */   len += sprintf (buf + len, "Subsystem PUN: %d\n", shpnt->this_id);   len += sprintf (buf + len, "I/O base address range: 0x%x-0x%x\n",		   (unsigned int)(shpnt->io_port),		   (unsigned int)(shpnt->io_port+7));   len += sprintf (buf + len, "MCA-slot size: %d bits",connectore);   /* Now make sure, the bufferlength is devidable by 4 to avoid    * paging problems of the buffer. */   while ( len % sizeof( int ) != ( sizeof ( int ) - 1 ) )     len += sprintf (buf+len, " ");   len += sprintf (buf+len, "\n");   IBMUNLOCK   return len;}int ibmmca_detect (Scsi_Host_Template * scsi_template){   struct Scsi_Host *shpnt;   int port, id, i, j, k, list_size, slot;   int devices_on_irq_11 = 0;   int devices_on_irq_14 = 0;   int IRQ14_registered = 0;   int IRQ11_registered = 0;   found = 0; /* make absolutely sure, that found is set to 0 */   /* First of all, print the version number of the driver. This is    * important to allow better user bugreports in case of already    * having problems with the MCA_bus probing. */   printk("IBM MCA SCSI: Version %s\n",IBMMCA_SCSI_DRIVER_VERSION);   /* if this is not MCA machine, return "nothing found" */   if (!MCA_bus) {      printk("IBM MCA SCSI:  No Microchannel-bus present --> Aborting.\n"	     "      	     This machine does not have any IBM MCA-bus\n"	     "    	     or the MCA-Kernel-support is not enabled!\n");      return 0;   }#ifdef MODULE   /* If the driver is run as module, read from conf.modules or cmd-line */   if (boot_options) option_setup(boot_options);#endif   /* get interrupt request level */   if (request_irq (IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmcascsi",		    hosts)) {      printk("IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ);      return 0;   } else     IRQ14_registered++;   /* if ibmmcascsi setup option was passed to kernel, return "found" */   for (i = 0; i < IM_MAX_HOSTS; i++)     if (io_port[i] > 0 && scsi_id[i] >= 0 && scsi_id[i] < 8) {	printk("IBM MCA SCSI: forced detected SCSI Adapter, io=0x%x, scsi id=%d.\n",	       io_port[i], scsi_id[i]);	if ((shpnt = ibmmca_register(scsi_template, io_port[i], scsi_id[i],		     FORCED_DETECTION, "forced detected SCSI Adapter"))) {	   for (k=2;k<7;k++)	     ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos[k] = 0;	   ((struct ibmmca_hostdata *)shpnt->hostdata)->_special = FORCED_DETECTION;	   mca_set_adapter_name(MCA_INTEGSCSI, "forced detected SCSI Adapter");	   mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,				  shpnt);	   mca_mark_as_used(MCA_INTEGSCSI);	   devices_on_irq_14++;	}     }   if (found) return found;   /* The POS2-register of all PS/2 model SCSI-subsystems has the following    * interpretation of bits:    *                             Bit 7 - 4 : Chip Revision ID (Release)    *                             Bit 3 - 2 : Reserved    *                             Bit 1     : 8k NVRAM Disabled    *                             Bit 0     : Chip Enable (EN-Signal)    * The POS3-register is interpreted as follows:    *                             Bit 7 - 5 : SCSI ID    *                             Bit 4     : Reserved = 0    *                             Bit 3 - 0 : Reserved = 0    * (taken from "IBM, PS/2 Hardware Interface Technical Reference, Common    * Interfaces (1991)").    * In short words, this means, that IBM PS/2 machines only support    * 1 single subsystem by default. The slot-adapters must have another    * configuration on pos2. Here, one has to assume the following    * things for POS2-register:    *                             Bit 7 - 4 : Chip Revision ID (Release)    *                             Bit 3 - 1 : port offset factor    *                             Bit 0     : Chip Enable (EN-Signal)    * As I found a patch here, setting the IO-registers to 0x3540 forced,    * as there was a 0x05 in POS2 on a model 56, I assume, that the    * port 0x3540 must be fix for integrated SCSI-controllers.    * Ok, this discovery leads to the following implementation: (M.Lang) */   /* first look for the IBM SCSI integrated subsystem on the motherboard */   for (j=0;j<8;j++) /* read the pos-information */     pos[j] = mca_read_stored_pos(MCA_INTEGSCSI,j);   /* pos2 = pos3 = 0xff if there is no integrated SCSI-subsystem present, but    * if we ignore the settings of all surrounding pos registers, it is not    * completely sufficient to only check pos2 and pos3. */   /* Therefore, now the following if statement is used to    * make sure, we see a real integrated onboard SCSI-interface and no    * internal system information, which gets mapped to some pos registers    * on models 95xx. */   if ((!pos[0] && !pos[1] && pos[2]>0 && pos[3]>0 && !pos[4] && !pos[5] && !pos[6] && !pos[7]) ||       (pos[0]==0xff && pos[1]==0xff && pos[2]<0xff && pos[3]<0xff && pos[4]==0xff && pos[5]==0xff && pos[6]==0xff && pos[7]==0xff)) {      if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */	port = IM_IO_PORT;      else { /* if disabled, no IRQs will be generated, as the chip won't	      * listen to the incomming commands and will do really nothing,	      * except for listening to the pos-register settings. If this	      * happens, I need to hugely think about it, as one has to	      * write something to the MCA-Bus pos register in order to	      * enable the chip. Normally, IBM-SCSI won't pass the POST,	      * when the chip is disabled (see IBM tech. ref.). */	 port = IM_IO_PORT; /* anyway, set the portnumber and warn */	 printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n"		"              SCSI-operations may not work.\n");      }      id = (pos[3] & 0xe0) >> 5; /* this is correct and represents the PUN */      /* give detailed information on the subsystem. This helps me       * additionally during debugging and analyzing bug-reports. */      printk("IBM MCA SCSI: IBM Integrated SCSI Controller found, io=0x%x, scsi id=%d,\n"	     "              chip rev.=%d, 8K NVRAM=%s, subsystem=%s\n",	     port, id,	     ((pos[2] & 0xf0) >> 4), (pos[2] & 2) ? "locked" : "accessible",	     (pos[2] & 1) ? "enabled." : "disabled.");      /* register the found integrated SCSI-subsystem */      if ((shpnt = ibmmca_register(scsi_template, port, id, INTEGRATED_SCSI,				   "IBM Integrated SCSI Controller"))) {	 for (k=2;k<7;k++)	   ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos[k] = pos[k];	 ((struct ibmmca_hostdata *)shpnt->hostdata)->_special = INTEGRATED_SCSI;	 mca_set_adapter_name(MCA_INTEGSCSI, "IBM Integrated SCSI Controller");	 mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,				shpnt);	 mca_mark_as_used(MCA_INTEGSCSI);	 devices_on_irq_14++;      }   }   /* now look for other adapters in MCA slots, */   /* determine the number of known IBM-SCSI-subsystem types */   /* see the pos[2] dependence to get the adapter port-offset. */   list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);   for (i = 0; i < list_size; i++) {      /* scan each slot for a fitting adapter id */      slot = 0; /* start at slot 0 */      while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot))	     != MCA_NOTFOUND) { /* scan through all slots */	 for (j=0;j<8;j++) /* read the pos-information */	   pos[j] = mca_read_stored_pos(slot, j);	 if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */	   /* (explanations see above) */	   port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);	 else {	    /* anyway, set the portnumber and warn */	    port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);	    printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n"		   "              SCSI-operations may not work.\n");	 }	 if ((i==IBM_SCSI2_FW)&&(pos[6]!=0)) {	    printk("IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n"		   "              Impossible to determine adapter PUN!\n"		   "              Guessing adapter PUN = 7.\n");	    id = 7;	 } else {	    id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */	    if (i==IBM_SCSI2_FW) {	       id |= (pos[3] & 0x10) >> 1; /* get subsystem PUN high-bit					    * for F/W adapters */	    }	 }	 if ((i==IBM_SCSI2_FW)&&(pos[4] & 0x01)&&(pos[6]==0)) {	    /* IRQ11 is used by SCSI-2 F/W Adapter/A */	    printk("IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");	    /* get interrupt request level */	    if (request_irq (IM_IRQ_FW, interrupt_handler, SA_SHIRQ,			     "ibmmcascsi", hosts)) {	       printk("IBM MCA SCSI: Unable to get shared IRQ %d.\n",		      IM_IRQ_FW);	    } else	      IRQ11_registered++;	 }	 printk("IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n",		subsys_list[i].description, slot + 1, port, id);	 if ((pos[2] & 0xf0) == 0xf0)	   printk("              ROM Addr.=off,");	 else	   printk("              ROM Addr.=0x%x,",		  ((pos[2] & 0xf0) << 13) + 0xc0000);	 printk(" port-offset=0x%x, subsystem=%s\n",		((pos[2] & 0x0e) << 2),		(pos[2] & 1) ? "enabled." : "disabled.");	 /* register the hostadapter */	 if ((shpnt = ibmmca_registe

⌨️ 快捷键说明

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