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

📄 fdomain.c

📁 linux0.99源代码用于研究linux操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
   printk( "Future Domain detection routine scanning for devices:\n" );   for (i = 0; i < 8; i++) {      SCinit.target = i;      if (i == 6) continue;	/* The host adapter is at SCSI ID 6 */      memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));      retcode = fdomain_16x0_command(&SCinit);      if (!retcode) {	 memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));	 retcode = fdomain_16x0_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 = fdomain_16x0_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)",		      ((capacity + 5L) / 10L), size );	    } else {	       memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));	       retcode = fdomain_16x0_command(&SCinit);	    }	    printk ("\n" );	 } else {	    memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));	    retcode = fdomain_16x0_command(&SCinit);	 }      }   }#endif   this_host      = hostnum;      if (!QUEUE || !interrupt_level) {      printk( "Future Domain: *NO* interrupt level selected!\n" );      printk( "               COMMAND QUEUEING DISABLED!\n" );      can_queue = scsi_hosts[this_host].can_queue = 0;      scsi_hosts[this_host].sg_tablesize = SG_NONE;   } else {      /* Register the IRQ with the kernel */      sa.sa_handler  = fdomain_16x0_intr;      sa.sa_flags    = SA_INTERRUPT;      sa.sa_mask     = 0;      sa.sa_restorer = NULL;            retcode = irqaction( interrupt_level, &sa );      if (retcode < 0) {	 if (retcode == -EINVAL) {	    printk( "Future Domain: IRQ %d is bad!\n", interrupt_level );	    printk( "               This shouldn't happen: REPORT TO RIK!\n" );	 } else if (retcode == -EBUSY) {	    printk( "Future Domain: IRQ %d is already in use!\n",		   interrupt_level );	    printk( "               Please use another IRQ for the FD card!\n" );	 } else {	    printk( "Future Domain: Error getting IRQ %d\n", interrupt_level );	    printk( "               This shouldn't happen: REPORT TO RIK!\n" );	 }	 printk( "               COMMAND QUEUEING DISABLED!\n" );      	 can_queue = scsi_hosts[this_host].can_queue = 0;	 scsi_hosts[this_host].sg_tablesize = SG_NONE;      } else {	 printk( "Future Domain: IRQ %d requested from kernel\n",		interrupt_level );      }   }      return 1;}const char *fdomain_16x0_info(void){   static char buffer[] =	 "Future Domain TMC-1660/TMC-1680 SCSI driver version "	       VERSION		     "\n";   return buffer;}static int fdomain_arbitrate( void ){   int           status = 0;   unsigned long timeout;#if EVERY_ACCESS   printk( "SCSI: fdomain_arbitrate()\n" );#endif      outb( 0x00, SCSI_Cntl_port );              /* Disable data drivers */   outb( 0x40, port_base + SCSI_Data_NoACK ); /* Set our id bit */   outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */   timeout = jiffies + 50;	              /* 500 mS */   while (jiffies < timeout) {      status = inb( TMC_Status_port );        /* Read adapter status */      if (status & 0x02) return 0;            /* Arbitration complete */   }   /* Make bus idle */   fdomain_make_bus_idle();#if EVERY_ACCESS   printk( "Arbitration failed, status = %x\n", status );#endif#if ERRORS_ONLY   printk( "SCSI (Future Domain): Arbitration failed, status = %x",	  status );#endif   return 1;}static int fdomain_select( int target ){   int           status;   unsigned long timeout;   /* Send our address OR'd with target address */   outb( 0x40 | (1 << target), SCSI_Data_NoACK_port );   if (RESELECTION && can_queue)	 outb( 0x8a, SCSI_Cntl_port ); /* Bus Enable + Attention + Select */   else	 outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */   /* Stop arbitration (also set FIFO for output and enable parity) */   outb( 0xc0 | PARITY_MASK, TMC_Cntl_port );    timeout = jiffies + 25;	        /* 250mS */   while (jiffies < timeout) {      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;      }   }   /* Make bus idle */   fdomain_make_bus_idle();#if EVERY_ACCESS   if (!target) printk( "Selection failed\n" );#endif#if ERRORS_ONLY   if (!target) printk( "SCSI (Future Domain): Selection failed" );#endif   return 1;}void my_done( int error ){   if (in_command) {      in_command = 0;      in_interrupt_code = 0;      outb( 0x00, Interrupt_Cntl_port );      fdomain_make_bus_idle();      current_SC->result = error;      if (current_SC->scsi_done) current_SC->scsi_done( current_SC );      else panic( "SCSI (Future Domain): current_SC->scsi_done() == NULL" );   } else {      panic( "SCSI (Future Domain): my_done() called outside of command\n" );   }}void fdomain_16x0_intr( int unused ){   int      status;   int      done = 0;   unsigned data_count;   sti();   if (in_interrupt_code)	 panic( "SCSI (Future Domain): fdomain_16x0_intr() NOT REENTRANT!\n" );   else	 ++in_interrupt_code;      outb( 0x00, Interrupt_Cntl_port );   if (current_SC->SCp.phase & aborted) {#if EVERY_ACCESS      if (current_SC->SCp.phase & (in_other || disconnect))	    printk( "aborted (%s) = %d, ",		   current_SC->SCp.phase & in_other		   ? "in_other" : "disconnect",		   current_SC->result );      else	    printk( "aborted = %d, ",		   current_SC->result );#endif      /* Force retry for timeouts after selection complete */      if (current_SC->SCp.phase & (in_other || disconnect)) {	 fdomain_16x0_reset();	 my_done( DID_RESET << 16 );      } else {	 my_done( current_SC->result << 16 );      }      return;   }   /* We usually have one spurious interrupt after each command.  Ignore it. */   if (!in_command) {		/* Spurious interrupt */      in_interrupt_code = 0;      return;   }#if RESELECTION   if (current_SC->SCp.phase & disconnect) {      printk( " RECON %x ", inb( SCSI_Data_NoACK_port ) );      current_SC->SCp.phase = in_other;      outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );      outb( 0x84, SCSI_Cntl_port );      while ( (status = inb( SCSI_Status_port )) & 0x20 ) {	 printk( "s = %x, ", status );      }      outb( 0x80, SCSI_Cntl_port );   } else#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	 my_done( DID_BUS_BUSY << 16 );	 return;      }      current_SC->SCp.phase = in_selection;      outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );      outb( 0x40 | (1 << current_SC->target), SCSI_Data_NoACK_port );#if RESELECTION      outb( 0x8a, SCSI_Cntl_port ); /* Bus Enable + Attention + Select */#else      outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */#endif      /* Stop arbitration (also set FIFO for output and enable parity) */      outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );      in_interrupt_code = 0;      return;   } else if (current_SC->SCp.phase & in_selection) {      status = inb( SCSI_Status_port );      if (!(status & 0x01)) {	 /* Try again, for slow devices */	 if (fdomain_select( current_SC->target )) {#if EVERY_ACCESS	    printk( " SFAIL " );#endif	    my_done( DID_NO_CONNECT << 16 );	    return;	 } else {#if EVERY_ACCESS	 printk( " AltSel " );#endif	 /* Stop arbitration (also set FIFO for output and enable parity) */	 outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );       }      }      current_SC->SCp.phase = in_other;      in_interrupt_code = 0;      outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );#if RESELECTION      outb( 0x88, SCSI_Cntl_port );#else      outb( 0x80, SCSI_Cntl_port );#endif      return;   }   /* current_SC->SCp.phase == in_other: this is the body of the routine */   switch (current_SC->cmnd[0]) {   case 0x04: case 0x07: case 0x0a: case 0x15: case 0x2a:   case 0x2e: case 0x3b: case 0xea: case 0x3f:      while ( (data_count = 0x2000 - inw( FIFO_Data_Count_port )) > 512 ) {#if EVERY_ACCESS	 printk( "DC=%d, ", data_count );#endif	 if (data_count > current_SC->SCp.this_residual)	       data_count = current_SC->SCp.this_residual;	 if (data_count > 0) {#if EVERY_ACCESS	    printk( "%d OUT, ", data_count );#endif	    if (data_count == 1) {	       outb( *current_SC->SCp.ptr++, Write_FIFO_port );	       --current_SC->SCp.this_residual;	    } else {	       data_count >>= 1;	       outsw( current_SC->SCp.ptr, data_count, Write_FIFO_port );	       current_SC->SCp.ptr += 2 * data_count;	       current_SC->SCp.this_residual -= 2 * data_count;	    }	 }	 if (!current_SC->SCp.this_residual) {	    if (current_SC->SCp.buffers_residual) {	       --current_SC->SCp.buffers_residual;	       ++current_SC->SCp.buffer;	       current_SC->SCp.ptr = current_SC->SCp.buffer->address;	       current_SC->SCp.this_residual = current_SC->SCp.buffer->length;	    } else		  break;	 }      }      break;   default:      if (!current_SC->SCp.have_data_in) {	 outb( 0x90 | PARITY_MASK, TMC_Cntl_port );	 ++current_SC->SCp.have_data_in;      } else {	 while ((data_count = inw( FIFO_Data_Count_port )) != 0) {#if EVERY_ACCESS	    printk( "DC=%d, ", data_count );#endif	    if (data_count > current_SC->SCp.this_residual)		  data_count = current_SC->SCp.this_residual;	    if (data_count) {#if EVERY_ACCESS	       printk( "%d IN, ", data_count );#endif	       if (data_count == 1) {		  *current_SC->SCp.ptr++ = inb( Read_FIFO_port );		  --current_SC->SCp.this_residual;	       } else {		  data_count >>= 1; /* Number of words */		  insw( current_SC->SCp.ptr, data_count, Read_FIFO_port );		  current_SC->SCp.ptr += 2 * data_count;		  current_SC->SCp.this_residual -= 2 * data_count;	       }	    }	    if (!current_SC->SCp.this_residual && current_SC->SCp.buffers_residual) {	       --current_SC->SCp.buffers_residual;	       ++current_SC->SCp.buffer;	       current_SC->SCp.ptr = current_SC->SCp.buffer->address;	       current_SC->SCp.this_residual = current_SC->SCp.buffer->length;	    }	 }      }      break;   }   status = inb( SCSI_Status_port );   if (status & 0x10) {	/* REQ */            switch (status & 0x0e) {      case 0x08:		/* COMMAND OUT */#if 0	 if (!current_SC->SCp.sent_command) {	    int i;	    	    ++current_SC->SCp.sent_command;	    	    for (i = 0; i < COMMAND_SIZE( current_SC->cmnd[0] ); i++) {	       outb( current_SC->cmnd[i], Write_SCSI_Data_port );#if EVERY_ACCESS	       printk( "CMD = %x,", current_SC->cmnd[i] );#endif	    }	 }#else	 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	    #endif	 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) {	    printk( "SCSI (Future Domain): target = %d, command = %x, Status = %x\n",		   current_SC->target, current_SC->cmnd[0], current_SC->SCp.Status );	 }#endif	 break;      case 0x0a:		/* MESSAGE OUT */#if RESELECTION	 if (!(current_SC->SCp.phase & sent_ident)) {#if EVERY_ACCESS	    printk( " IDENT " );#endif	    outb( 0x80, SCSI_Cntl_port );	    outb( IDENTIFY( 1, 0 ), Write_SCSI_Data_port );	    current_SC->SCp.phase |= sent_ident;	 } else#else	       outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */#endif	 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 RESELECTION	 if (current_SC->SCp.Message == DISCONNECT) {	    printk( " DISCON " );	    current_SC->SCp.phase = disconnect;	 }#endif#if DEBUG_MESSAGES || EVERY_ACCESS	 if (current_SC->SCp.Message) {	    printk( "SCSI (Future Domain): Message = %x\n",		   current_SC->SCp.Message );	 }#endif	 break;

⌨️ 快捷键说明

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