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

📄 aha152x.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
    else      printk("\naha152x: invalid module argument aha152x=0x%x,%d,%d,%d,%d,%d,%d,%d\n",             setup[setup_count].io_port,             setup[setup_count].irq,             setup[setup_count].scsiid,             setup[setup_count].reconnect,             setup[setup_count].parity,             setup[setup_count].synchronous,             setup[setup_count].delay,             setup[setup_count].ext_trans);  }  if(setup_count<2 && aha152x1[0]!=0) {    setup[setup_count].conf        = "";    setup[setup_count].io_port     = aha152x1[0];    setup[setup_count].irq         = aha152x1[1];    setup[setup_count].scsiid      = aha152x1[2];    setup[setup_count].reconnect   = aha152x1[3];    setup[setup_count].parity      = aha152x1[4];    setup[setup_count].synchronous = aha152x1[5];    setup[setup_count].delay       = aha152x1[6];    setup[setup_count].ext_trans   = aha152x1[7];#ifdef DEBUG_AHA152X    setup[setup_count].debug       = aha152x1[8];#endif    if(aha152x_checksetup(&setup[setup_count]))      setup_count++;    else      printk("\naha152x: invalid module argument aha152x1=0x%x,%d,%d,%d,%d,%d,%d,%d\n",             setup[setup_count].io_port,             setup[setup_count].irq,             setup[setup_count].scsiid,             setup[setup_count].reconnect,             setup[setup_count].parity,             setup[setup_count].synchronous,             setup[setup_count].delay,             setup[setup_count].ext_trans);  }#endif  #if defined(AUTOCONF)  if(setup_count<2) {#if !defined(SKIP_BIOSTEST)    ok=0;    for(i=0; i < ADDRESS_COUNT && !ok; i++)      for(j=0; (j < SIGNATURE_COUNT) && !ok; j++)        ok=!memcmp((void *) addresses[i]+signatures[j].sig_offset,                   (void *) signatures[j].signature,                   (int) signatures[j].sig_length);    if(!ok && setup_count==0)      return 0;    printk("aha152x: BIOS test: passed, ");#else    printk("aha152x: ");#endif /* !SKIP_BIOSTEST */     ok=0;    for(i=0; i<PORT_COUNT && setup_count<2; i++) {      if((setup_count==1) && (setup[0].io_port == ports[i]))        continue;      if(aha152x_porttest(ports[i])) {        ok++;        setup[setup_count].io_port = ports[i];                      conf.cf_port =          (GETPORT(ports[i]+O_PORTA)<<8) + GETPORT(ports[i]+O_PORTB);                      setup[setup_count].irq         = IRQ_MIN + conf.cf_irq;        setup[setup_count].scsiid      = conf.cf_id;        setup[setup_count].reconnect   = conf.cf_tardisc;        setup[setup_count].parity      = !conf.cf_parity;        setup[setup_count].synchronous = 0 /* FIXME: conf.cf_syncneg */;        setup[setup_count].delay       = DELAY_DEFAULT;        setup[setup_count].ext_trans   = 0;#ifdef DEBUG_AHA152X        setup[setup_count].debug       = DEBUG_DEFAULT;#endif        setup_count++;      }    }    if(ok)      printk("auto configuration: ok, ");  }#endif  printk("detected %d controller(s)\n", setup_count);  for(i=0; i<setup_count; i++) {    struct Scsi_Host        *shpnt;    unsigned long int       the_time;    shpnt = aha152x_host[setup[i].irq-IRQ_MIN] =      scsi_register(tpnt, sizeof(struct aha152x_hostdata));    shpnt->io_port                     = setup[i].io_port;    shpnt->n_io_port                   = IO_RANGE;    shpnt->irq                         = setup[i].irq;    ISSUE_SC                           = (Scsi_Cmnd *) NULL;    CURRENT_SC                         = (Scsi_Cmnd *) NULL;    DISCONNECTED_SC                    = (Scsi_Cmnd *) NULL;    HOSTDATA(shpnt)->reconnect         = setup[i].reconnect;    HOSTDATA(shpnt)->parity            = setup[i].parity;    HOSTDATA(shpnt)->synchronous       = setup[i].synchronous;    HOSTDATA(shpnt)->delay             = setup[i].delay;    HOSTDATA(shpnt)->ext_trans         = setup[i].ext_trans;#ifdef DEBUG_AHA152X    HOSTDATA(shpnt)->debug             = setup[i].debug;#endif    HOSTDATA(shpnt)->aborting          = 0;    HOSTDATA(shpnt)->abortion_complete = 0;    HOSTDATA(shpnt)->abort_result      = 0;    HOSTDATA(shpnt)->commands          = 0;    HOSTDATA(shpnt)->message_len       = 0;    for(j=0; j<8; j++)      HOSTDATA(shpnt)->syncrate[j] = 0;     SETPORT(SCSIID, setup[i].scsiid << 4);    shpnt->this_id=setup[i].scsiid;      if(setup[i].reconnect)      shpnt->can_queue=AHA152X_MAXQUEUE;    /* RESET OUT */    SETBITS(SCSISEQ, SCSIRSTO);    do_pause(30);    CLRBITS(SCSISEQ, SCSIRSTO);    do_pause(setup[i].delay);    aha152x_reset_ports(shpnt);          printk("aha152x%d: vital data: PORTBASE=0x%03x, IRQ=%d, SCSI ID=%d,"           " reconnect=%s, parity=%s, synchronous=%s, delay=%d, extended translation=%s\n",           i,           shpnt->io_port,           shpnt->irq,           shpnt->this_id,           HOSTDATA(shpnt)->reconnect ? "enabled" : "disabled",           HOSTDATA(shpnt)->parity ? "enabled" : "disabled",           HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled",           HOSTDATA(shpnt)->delay,           HOSTDATA(shpnt)->ext_trans ? "enabled" : "disabled");    request_region(shpnt->io_port, IO_RANGE, "aha152x");  /* Register */      /* not expecting any interrupts */    SETPORT(SIMODE0, 0);    SETPORT(SIMODE1, 0);    SETBITS(DMACNTRL0, INTEN);    ok = request_irq(shpnt->irq, aha152x_swintr, SA_INTERRUPT, "aha152x", NULL);    if(ok<0) {      if(ok == -EINVAL)        printk("aha152x%d: bad IRQ %d.\n", i, shpnt->irq);      else if(ok == -EBUSY)        printk("aha152x%d: IRQ %d already in use.\n", i, shpnt->irq);      else        printk("\naha152x%d: Unexpected error code %d on requesting IRQ %d.\n",                 i, ok, shpnt->irq);      printk("aha152x: driver needs an IRQ.\n");      scsi_unregister(shpnt);      shpnt=aha152x_host[shpnt->irq-IRQ_MIN]=0;      continue;    }    HOSTDATA(shpnt)->swint=0;    printk("aha152x: trying software interrupt, ");    SETBITS(DMACNTRL0, SWINT);    the_time=jiffies+100;    while(!HOSTDATA(shpnt)->swint && jiffies<the_time)      barrier();    free_irq(shpnt->irq,0);    if(!HOSTDATA(shpnt)->swint) {      if(TESTHI(DMASTAT, INTSTAT)) {        printk("lost.\n");      } else {        printk("failed.\n");      }      printk("aha152x: IRQ %d possibly wrong.  Please verify.\n", shpnt->irq);      scsi_unregister(shpnt);      shpnt=aha152x_host[shpnt->irq-IRQ_MIN]=0;      continue;    }    printk("ok.\n");    CLRBITS(DMACNTRL0, SWINT);    /* clear interrupts */    SETPORT(SSTAT0, 0x7f);    SETPORT(SSTAT1, 0xef);    if(request_irq(shpnt->irq,aha152x_intr,SA_INTERRUPT,"aha152x",NULL)<0) {      printk("aha152x: failed to reassign interrupt.\n");    }  }    return (setup_count>0);}/*  *  Queue a command and setup interrupts for a free bus. */int aha152x_queue(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)){  struct Scsi_Host *shpnt = SCpnt->host;  unsigned long flags;#if defined(DEBUG_RACE)  enter_driver("queue");#else#if defined(DEBUG_QUEUE)  if(HOSTDATA(shpnt)->debug & debug_queue)    printk("aha152x: queue(), ");#endif#endif#if defined(DEBUG_QUEUE)  if(HOSTDATA(shpnt)->debug & debug_queue) {    printk("SCpnt (target = %d lun = %d cmnd = ",           SCpnt->target, SCpnt->lun);    print_command(SCpnt->cmnd);    printk(", cmd_len=%d, pieces = %d size = %u), ",           SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen);    disp_ports(shpnt);  }#endif  SCpnt->scsi_done =       done;  /* setup scratch area     SCp.ptr              : buffer pointer     SCp.this_residual    : buffer length     SCp.buffer           : next buffer     SCp.buffers_residual : left buffers in list     SCp.phase            : current state of the command */  SCpnt->SCp.phase = not_issued;  if (SCpnt->use_sg) {    SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;    SCpnt->SCp.ptr              = SCpnt->SCp.buffer->address;    SCpnt->SCp.this_residual    = SCpnt->SCp.buffer->length;    SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;  } else {    SCpnt->SCp.ptr              = (char *)SCpnt->request_buffer;    SCpnt->SCp.this_residual    = SCpnt->request_bufflen;    SCpnt->SCp.buffer           = NULL;    SCpnt->SCp.buffers_residual = 0;  }            SCpnt->SCp.Status              = CHECK_CONDITION;  SCpnt->SCp.Message             = 0;  SCpnt->SCp.have_data_in        = 0;  SCpnt->SCp.sent_command        = 0;  /* Turn led on, when this is the first command. */  save_flags(flags);  cli();  HOSTDATA(shpnt)->commands++;  if(HOSTDATA(shpnt)->commands==1)    SETPORT(PORTA, 1);#if defined(DEBUG_QUEUES)  if(HOSTDATA(shpnt)->debug & debug_queues)    printk("i+ (%d), ", HOSTDATA(shpnt)->commands);#endif  append_SC(&ISSUE_SC, SCpnt);    /* Enable bus free interrupt, when we aren't currently on the bus */  if(!CURRENT_SC) {    SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);    SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);  }  restore_flags(flags);#if defined(DEBUG_RACE)  leave_driver("queue");#endif  return 0;}/* *  We only support commands in interrupt-driven fashion */int aha152x_command(Scsi_Cmnd *SCpnt){  printk("aha152x: interrupt driven driver; use aha152x_queue()\n");  return -1;}/* *  Abort a queued command *  (commands that are on the bus can't be aborted easily) */int aha152x_abort(Scsi_Cmnd *SCpnt){  struct Scsi_Host *shpnt = SCpnt->host;  unsigned long flags;  Scsi_Cmnd *ptr, *prev;  save_flags(flags);  cli();#if defined(DEBUG_ABORT)  if(HOSTDATA(shpnt)->debug & debug_abort) {     printk("aha152x: abort(), SCpnt=0x%08x, ", (unsigned int) SCpnt);    show_queues(shpnt);  }#endif  /* look for command in issue queue */  for(ptr=ISSUE_SC, prev=NULL;       ptr && ptr!=SCpnt;       prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble)    ;  if(ptr) {    /* dequeue */    if(prev)      prev->host_scribble = ptr->host_scribble;    else      ISSUE_SC = (Scsi_Cmnd *) ptr->host_scribble;    HOSTDATA(shpnt)->commands--;     restore_flags(flags);    ptr->host_scribble = NULL;    ptr->result = DID_ABORT << 16;    ptr->scsi_done(ptr);    return SCSI_ABORT_SUCCESS;  }  /* if the bus is busy or a command is currently processed,     we can't do anything more */  if (TESTLO(SSTAT1, BUSFREE) || (CURRENT_SC && CURRENT_SC!=SCpnt)) {    /* fail abortion, if bus is busy */    if(!CURRENT_SC)      printk("bus busy w/o current command, ");     restore_flags(flags);    return SCSI_ABORT_BUSY;  }  /* bus is free */  if(CURRENT_SC) {     HOSTDATA(shpnt)->commands--;     /* target entered bus free before COMMAND COMPLETE, nothing to abort */    restore_flags(flags);    CURRENT_SC->result = DID_ERROR << 16;    CURRENT_SC->scsi_done(CURRENT_SC);    CURRENT_SC = (Scsi_Cmnd *) NULL;    return SCSI_ABORT_SUCCESS;  }  /* look for command in disconnected queue */  for(ptr=DISCONNECTED_SC, prev=NULL;       ptr && ptr!=SCpnt;       prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble)    ;  if(!ptr) {    /* command wasn't found */    printk("command not found\n");    restore_flags(flags);    return SCSI_ABORT_NOT_RUNNING;  }  if(!HOSTDATA(shpnt)->aborting) {    /* dequeue */    if(prev)      prev->host_scribble = ptr->host_scribble;    else      DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble;    HOSTDATA(shpnt)->commands--;     /* set command current and initiate selection,       let the interrupt routine take care of the abortion */    CURRENT_SC     = ptr;    ptr->SCp.phase = in_selection|aborted;    SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target);          ADDMSG(ABORT);    /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */    SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));    SETPORT(SIMODE1, ENSELTIMO);    /* Enable SELECTION OUT sequence */    SETBITS(SCSISEQ, ENSELO | ENAUTOATNO);    SETBITS(DMACNTRL0, INTEN);    HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS;    HOSTDATA(shpnt)->aborting++;    HOSTDATA(shpnt)->abortion_complete=0;    sti();  /* Hi Eric, guess what ;-) */    /* sleep until the abortion is complete */    while(!HOSTDATA(shpnt)->abortion_complete)      barrier();    HOSTDATA(shpnt)->aborting=0;    return HOSTDATA(shpnt)->abort_result;  } else {    /* we're already aborting a command */    restore_flags(flags);    return SCSI_ABORT_BUSY;  }}/* *  Restore default values to the AIC-6260 registers and reset the fifos */static void aha152x_reset_ports(struct Scsi_Host *shpnt){  /* disable interrupts */  SETPORT(DMACNTRL0, RSTFIFO);  SETPORT(SCSISEQ, 0);  SETPORT(SXFRCTL1, 0);  SETPORT(SCSISIG, 0);  SETPORT(SCSIRATE, 0);

⌨️ 快捷键说明

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