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

📄 fd_mcs.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
	Read_FIFO_port        = port + Read_FIFO;	Read_SCSI_Data_port   = port + Read_SCSI_Data;	SCSI_Cntl_port        = port + SCSI_Cntl;	SCSI_Data_NoACK_port  = port + SCSI_Data_NoACK;	SCSI_Status_port      = port + SCSI_Status;	TMC_Cntl_port         = port + TMC_Cntl;	TMC_Status_port       = port + TMC_Status;	Write_FIFO_port       = port + Write_FIFO;	Write_SCSI_Data_port  = port + Write_SCSI_Data;	Bytes_Read     = 0;	Bytes_Written  = 0;	INTR_Processed = 0;	/* say something */	print_banner( shpnt );	/* reset */	outb( 1, SCSI_Cntl_port );	do_pause( 2 );	outb( 0, SCSI_Cntl_port );	do_pause( 115 );	outb( 0, SCSI_Mode_Cntl_port );	outb( PARITY_MASK, TMC_Cntl_port );	/* done reset */#if DO_DETECT	/* scan devices attached */	{	  const int     buflen = 255;	  int           i, j, retcode;	  Scsi_Cmnd     SCinit;	  unsigned char do_inquiry[] =       { INQUIRY, 0, 0, 0, buflen, 0 };	  unsigned char do_request_sense[] = { REQUEST_SENSE, 					       0, 0, 0, buflen, 0 };	  unsigned char do_read_capacity[] = { READ_CAPACITY,					       0, 0, 0, 0, 0, 0, 0, 0, 0 };	  unsigned char buf[buflen];	  SCinit.request_buffer  = SCinit.buffer = buf;	  SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;	  SCinit.use_sg          = 0;	  SCinit.lun             = 0;	  SCinit.host            = shpnt;	  printk( "fd_mcs: detection routine scanning for devices:\n" );	  for (i = 0; i < 8; i++) {	    if (i == shpnt->this_id)	/* Skip host adapter */	      continue;	    SCinit.target = i;	    memcpy(SCinit.cmnd, do_request_sense,		   sizeof(do_request_sense));	    retcode = fd_mcs_command(&SCinit);	    if (!retcode) {	      memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));	      retcode = fd_mcs_command(&SCinit);	      if (!retcode) {		printk( "     SCSI ID %d: ", i );		for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)		  printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );		memcpy(SCinit.cmnd, do_read_capacity,		       sizeof(do_read_capacity));		retcode = fd_mcs_command(&SCinit);		if (!retcode) {		  unsigned long blocks, size, capacity;	       		  blocks = (buf[0] << 24) | (buf[1] << 16)		    | (buf[2] << 8) | buf[3];		  size = (buf[4] << 24) | (buf[5] << 16) | 		    (buf[6] << 8) | buf[7];		  capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;	       		  printk( "%lu MB (%lu byte blocks)\n",			  ((capacity + 5L) / 10L), size );		}	      }	    }	  }	}#endif      }    }    if (found == FD_MAX_HOSTS) {      printk( "fd_mcs: detecting reached max=%d host adapters.\n",	      FD_MAX_HOSTS);      break;    }  }  return found;}const char *fd_mcs_info(struct Scsi_Host *shpnt){  return adapter_name;}static int TOTAL_INTR = 0;/* * inout : decides on the direction of the dataflow and the meaning of the  *         variables * buffer: If inout==FALSE data is being written to it else read from it * *start: If inout==FALSE start of the valid data in the buffer * offset: If inout==FALSE offset from the beginning of the imaginary file  *         from which we start writing into the buffer * length: If inout==FALSE max number of bytes to be written into the buffer  *         else number of bytes in the buffer */int fd_mcs_proc_info( char *buffer, char **start, off_t offset,		      int length, int hostno, int inout ){  struct Scsi_Host *shpnt;  int    len = 0;  int    i;  if (inout)    return(-ENOSYS);  *start = buffer + offset;  for (i = 0; hosts[i] && hosts[i]->host_no != hostno; i++);  shpnt = hosts[i];  if (!shpnt) {    return(-ENOENT);  } else {    len += sprintf(buffer+len, "Future Domain MCS-600/700 Driver %s\n",		   DRIVER_VERSION);    len += sprintf(buffer+len, "HOST #%d: %s\n",		   hostno, adapter_name);    len += sprintf(buffer+len, "FIFO Size=0x%x, FIFO Count=%d\n",		   FIFO_Size, FIFO_COUNT);    len += sprintf(buffer+len, "DriverCalls=%d, Interrupts=%d, BytesRead=%d, BytesWrite=%d\n\n",		   TOTAL_INTR, INTR_Processed, Bytes_Read, Bytes_Written);  }  if ((len -= offset) <= 0)    return 0;  if (len > length)     len = length;  return len;}   static int fd_mcs_select(struct Scsi_Host *shpnt, int target ){  int           status;  unsigned long timeout;  outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */  outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );  /* Stop arbitration and enable parity */  outb( PARITY_MASK, TMC_Cntl_port );   timeout = 350;		/* 350mS -- because of timeouts				   (was 250mS) */  do {    status = inb( SCSI_Status_port ); /* Read adapter status */    if (status & 1) {			/* Busy asserted */      /* Enable SCSI Bus (on error, should make bus idle with 0) */      outb( 0x80, SCSI_Cntl_port );      return 0;    }    udelay(1000);		/* wait one msec */  } while (--timeout);  /* Make bus idle */  fd_mcs_make_bus_idle(shpnt);#if EVERY_ACCESS  if (!target) printk( "Selection failed\n" );#endif#if ERRORS_ONLY  if (!target) {    static int flag = 0;    if (!flag) /* Skip first failure for all chips. */      ++flag;    else      printk( "fd_mcs: Selection failed\n" );  }#endif  return 1;}static void my_done( struct Scsi_Host *shpnt, int error ){  if (in_command) {    in_command = 0;    outb( 0x00, Interrupt_Cntl_port );    fd_mcs_make_bus_idle(shpnt);    current_SC->result = error;    current_SC->scsi_done( current_SC );  } else {    panic( "fd_mcs: my_done() called outside of command\n" );  }#if DEBUG_RACE  in_interrupt_flag = 0;#endif}/* only my_done needs to be protected  */static void fd_mcs_intr( int irq, void *dev_id, struct pt_regs * regs ){  unsigned long flags;  int      status;  int      done = 0;  unsigned data_count, tmp_count;  int i = 0;  struct Scsi_Host *shpnt;  TOTAL_INTR++;  /* search for one adapter-response on shared interrupt */  while ((shpnt = hosts[i++])) {    if ((inb(TMC_Status_port)) & 1)      break;  }   /* return if some other device on this IRQ caused the interrupt */  if (!shpnt) {    return;  }  INTR_Processed++;  outb( 0x00, Interrupt_Cntl_port );  /* Abort calls my_done, so we do nothing here. */  if (current_SC->SCp.phase & aborted) {#if DEBUG_ABORT    printk( "Interrupt after abort, ignoring\n" );#endif    /* return; */  }#if DEBUG_RACE  ++in_interrupt_flag;#endif  if (current_SC->SCp.phase & in_arbitration) {    status = inb( TMC_Status_port );        /* Read adapter status */    if (!(status & 0x02)) {#if EVERY_ACCESS      printk( " AFAIL " );#endif      spin_lock_irqsave(&io_request_lock, flags);      my_done( shpnt, DID_BUS_BUSY << 16 );      spin_unlock_irqrestore(&io_request_lock, flags);      return;    }    current_SC->SCp.phase = in_selection;          outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );    outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */    outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );          /* Stop arbitration and enable parity */    outb( 0x10 | PARITY_MASK, TMC_Cntl_port );#if DEBUG_RACE    in_interrupt_flag = 0;#endif    return;  } else if (current_SC->SCp.phase & in_selection) {    status = inb( SCSI_Status_port );    if (!(status & 0x01)) {      /* Try again, for slow devices */      if (fd_mcs_select(shpnt, current_SC->target )) {#if EVERY_ACCESS	printk( " SFAIL " );#endif	spin_lock_irqsave(&io_request_lock, flags);	my_done( shpnt, DID_NO_CONNECT << 16 );	spin_unlock_irqrestore(&io_request_lock, flags);	return;      } else {#if EVERY_ACCESS	printk( " AltSel " );#endif	/* Stop arbitration and enable parity */	outb( 0x10 | PARITY_MASK, TMC_Cntl_port );      }    }    current_SC->SCp.phase = in_other;    outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );    outb( 0x80, SCSI_Cntl_port );#if DEBUG_RACE    in_interrupt_flag = 0;#endif    return;  }     /* current_SC->SCp.phase == in_other: this is the body of the routine */     status = inb( SCSI_Status_port );     if (status & 0x10) {	/* REQ */          switch (status & 0x0e) {           case 0x08:		/* COMMAND OUT */      outb( current_SC->cmnd[current_SC->SCp.sent_command++],	    Write_SCSI_Data_port );#if EVERY_ACCESS      printk( "CMD = %x,",	      current_SC->cmnd[ current_SC->SCp.sent_command - 1] );#endif      break;    case 0x00:		/* DATA OUT -- tmc18c50/tmc18c30 only */      if (chip != tmc1800 && !current_SC->SCp.have_data_in) {	current_SC->SCp.have_data_in = -1;	outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );      }      break;    case 0x04:		/* DATA IN -- tmc18c50/tmc18c30 only */      if (chip != tmc1800 && !current_SC->SCp.have_data_in) {	current_SC->SCp.have_data_in = 1;	outb( 0x90 | PARITY_MASK, TMC_Cntl_port );      }      break;    case 0x0c:		/* STATUS IN */      current_SC->SCp.Status = inb( Read_SCSI_Data_port );#if EVERY_ACCESS      printk( "Status = %x, ", current_SC->SCp.Status );#endif#if ERRORS_ONLY      if (current_SC->SCp.Status	  && current_SC->SCp.Status != 2	  && current_SC->SCp.Status != 8) {	printk( "ERROR fd_mcs: target = %d, command = %x, status = %x\n",		current_SC->target,		current_SC->cmnd[0],		current_SC->SCp.Status );      }#endif      break;    case 0x0a:		/* MESSAGE OUT */      outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */      break;    case 0x0e:		/* MESSAGE IN */      current_SC->SCp.Message = inb( Read_SCSI_Data_port );#if EVERY_ACCESS      printk( "Message = %x, ", current_SC->SCp.Message );#endif      if (!current_SC->SCp.Message) ++done;#if DEBUG_MESSAGES || EVERY_ACCESS      if (current_SC->SCp.Message) {	printk( "fd_mcs: message = %x\n", current_SC->SCp.Message );      }#endif      break;    }  }  if (chip == tmc1800      && !current_SC->SCp.have_data_in      && (current_SC->SCp.sent_command	  >= current_SC->cmd_len)) {    /* We have to get the FIFO direction       correct, so I've made a table based       on the SCSI Standard of which commands       appear to require a DATA OUT phase.       */    /*      p. 94: Command for all device types      CHANGE DEFINITION            40 DATA OUT      COMPARE                      39 DATA OUT      COPY                         18 DATA OUT      COPY AND VERIFY              3a DATA OUT      INQUIRY                      12       LOG SELECT                   4c DATA OUT      LOG SENSE                    4d      MODE SELECT (6)              15 DATA OUT      MODE SELECT (10)             55 DATA OUT      MODE SENSE (6)               1a      MODE SENSE (10)              5a      READ BUFFER                  3c      RECEIVE DIAGNOSTIC RESULTS   1c      REQUEST SENSE                03      SEND DIAGNOSTIC              1d DATA OUT      TEST UNIT READY              00      WRITE BUFFER                 3b DATA OUT      p.178: Commands for direct-access devices (not listed on p. 94)      FORMAT UNIT                  04 DATA OUT      LOCK-UNLOCK CACHE            36      PRE-FETCH                    34      PREVENT-ALLOW MEDIUM REMOVAL 1e      READ (6)/RECEIVE             08      READ (10)                    3c      READ CAPACITY                25      READ DEFECT DATA (10)        37      READ LONG                    3e      REASSIGN BLOCKS              07 DATA OUT      RELEASE                      17      RESERVE                      16 DATA OUT      REZERO UNIT/REWIND           01      SEARCH DATA EQUAL (10)       31 DATA OUT      SEARCH DATA HIGH (10)        30 DATA OUT      SEARCH DATA LOW (10)         32 DATA OUT      SEEK (6)                     0b      SEEK (10)                    2b      SET LIMITS (10)              33      START STOP UNIT              1b      SYNCHRONIZE CACHE            35      VERIFY (10)                  2f      WRITE (6)/PRINT/SEND         0a DATA OUT      WRITE (10)/SEND              2a DATA OUT      WRITE AND VERIFY (10)        2e DATA OUT      WRITE LONG                   3f DATA OUT      WRITE SAME                   41 DATA OUT ?      p. 261: Commands for sequential-access devices (not previously listed)      ERASE                        19      LOAD UNLOAD                  1b      LOCATE                       2b      READ BLOCK LIMITS            05      READ POSITION                34      READ REVERSE                 0f      RECOVER BUFFERED DATA        14      SPACE                        11      WRITE FILEMARKS              10 ?      p. 298: Commands for printer devices (not previously listed)      ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****      SLEW AND PRINT               0b DATA OUT  -- same as seek      STOP PRINT                   1b      SYNCHRONIZE BUFFER           10      p. 315: Commands for processor devices (not previously listed)	      p. 321: Commands for write-once devices (not previously listed)      MEDIUM SCAN                  38      READ (12)                    a8      SEARCH DATA EQUAL (12)       b1 DATA OUT      SEARCH DATA HIGH (12)        b0 DATA OUT      SEARCH DATA LOW (12)         b2 DATA OUT      SET LIMITS (12)              b3      VERIFY (12)                  af      WRITE (12)                   aa DATA OUT      WRITE AND VERIFY (12)        ae DATA OUT      p. 332: Commands for CD-ROM devices (not previously listed)      PAUSE/RESUME                 4b      PLAY AUDIO (10)              45      PLAY AUDIO (12)              a5      PLAY AUDIO MSF               47      PLAY TRACK RELATIVE (10)     49      PLAY TRACK RELATIVE (12)     a9      READ HEADER                  44      READ SUB-CHANNEL             42      READ TOC                     43      p. 370: Commands for scanner devices (not previously listed)      GET DATA BUFFER STATUS       34      GET WINDOW                   25      OBJECT POSITION              31      SCAN                         1b      SET WINDOW                   24 DATA OUT      p. 391: Commands for optical memory devices (not listed)      ERASE (10)                   2c      ERASE (12)                   ac      MEDIUM SCAN                  38 DATA OUT      READ DEFECT DATA (12)        b7      READ GENERATION              29      READ UPDATED BLOCK           2d      UPDATE BLOCK                 3d DATA OUT      p. 419: Commands for medium changer devices (not listed)      EXCHANGE MEDIUM              46      INITIALIZE ELEMENT STATUS    07      MOVE MEDIUM                  a5      POSITION TO ELEMENT          2b      READ ELEMENT STATUS          b8      REQUEST VOL. ELEMENT ADDRESS b5      SEND VOLUME TAG              b6 DATA OUT      p. 454: Commands for communications devices (not listed previously)      GET MESSAGE (6)              08      GET MESSAGE (10)             28      GET MESSAGE (12)             a8      */

⌨️ 快捷键说明

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