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

📄 u14-34f.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
   printk ("%s: biosparam, head=%d, sec=%d, cyl=%d.\n", driver_name,           dkinfo[0], dkinfo[1], dkinfo[2]);#endif   return FALSE;}static void sort(unsigned long sk[], unsigned int da[], unsigned int n,                 unsigned int rev) {   unsigned int i, j, k, y;   unsigned long x;   for (i = 0; i < n - 1; i++) {      k = i;      for (j = k + 1; j < n; j++)         if (rev) {            if (sk[j] > sk[k]) k = j;            }         else {            if (sk[j] < sk[k]) k = j;            }      if (k != i) {         x = sk[k]; sk[k] = sk[i]; sk[i] = x;         y = da[k]; da[k] = da[i]; da[i] = y;         }      }   return;   }static inline int reorder(unsigned int j, unsigned long cursec,                 unsigned int ihdlr, unsigned int il[], unsigned int n_ready) {   Scsi_Cmnd *SCpnt;   struct mscp *cpp;   unsigned int k, n;   unsigned int rev = FALSE, s = TRUE, r = TRUE;   unsigned int input_only = TRUE, overlap = FALSE;   unsigned long sl[n_ready], pl[n_ready], ll[n_ready];   unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0;   unsigned long ioseek = 0;   static unsigned int flushcount = 0, batchcount = 0, sortcount = 0;   static unsigned int readycount = 0, ovlcount = 0, inputcount = 0;   static unsigned int readysorted = 0, revcount = 0;   static unsigned long seeksorted = 0, seeknosort = 0;   if (link_statistics && !(++flushcount % link_statistics))      printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d"\             " av %ldK as %ldK.\n", flushcount, batchcount, inputcount,             ovlcount, readycount, readysorted, sortcount, revcount,             seeknosort / (readycount + 1),             seeksorted / (readycount + 1));   if (n_ready <= 1) return FALSE;   for (n = 0; n < n_ready; n++) {      k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;      if (!(cpp->xdir == DTD_IN)) input_only = FALSE;      if (SCpnt->request.sector < minsec) minsec = SCpnt->request.sector;      if (SCpnt->request.sector > maxsec) maxsec = SCpnt->request.sector;      sl[n] = SCpnt->request.sector;      ioseek += SCpnt->request.nr_sectors;      if (!n) continue;      if (sl[n] < sl[n - 1]) s = FALSE;      if (sl[n] > sl[n - 1]) r = FALSE;      if (link_statistics) {         if (sl[n] > sl[n - 1])            seek += sl[n] - sl[n - 1];         else            seek += sl[n - 1] - sl[n];         }      }   if (link_statistics) {      if (cursec > sl[0]) seek += cursec - sl[0]; else seek += sl[0] - cursec;      }   if (cursec > ((maxsec + minsec) / 2)) rev = TRUE;   if (ioseek > ((maxsec - minsec) / 2)) rev = FALSE;   if (!((rev && r) || (!rev && s))) sort(sl, il, n_ready, rev);   if (!input_only) for (n = 0; n < n_ready; n++) {      k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;      ll[n] = SCpnt->request.nr_sectors; pl[n] = SCpnt->pid;      if (!n) continue;      if ((sl[n] == sl[n - 1]) || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n]))          || (rev && ((sl[n] + ll[n]) > sl[n - 1]))) overlap = TRUE;      }   if (overlap) sort(pl, il, n_ready, FALSE);   if (link_statistics) {      if (cursec > sl[0]) iseek = cursec - sl[0]; else iseek = sl[0] - cursec;      batchcount++; readycount += n_ready, seeknosort += seek / 1024;      if (input_only) inputcount++;      if (overlap) { ovlcount++; seeksorted += iseek / 1024; }      else seeksorted += (iseek + maxsec - minsec) / 1024;      if (rev && !r)     {  revcount++; readysorted += n_ready; }      if (!rev && !s)    { sortcount++; readysorted += n_ready; }      }#if defined(DEBUG_LINKED_COMMANDS)   if (link_statistics && (overlap || !(flushcount % link_statistics)))      for (n = 0; n < n_ready; n++) {         k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;         printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"\                " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",                (ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target,                SCpnt->lun, SCpnt->pid, k, flushcount, n_ready,                SCpnt->request.sector, SCpnt->request.nr_sectors, cursec,                YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only),                YESNO(overlap), cpp->xdir);         }#endif   return overlap;}static void flush_dev(Scsi_Device *dev, unsigned long cursec, unsigned int j,                      unsigned int ihdlr) {   Scsi_Cmnd *SCpnt;   struct mscp *cpp;   unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES];   for (k = 0; k < sh[j]->can_queue; k++) {      if (HD(j)->cp_stat[k] != READY && HD(j)->cp_stat[k] != IN_USE) continue;      cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;      if (SCpnt->device != dev) continue;      if (HD(j)->cp_stat[k] == IN_USE) return;      il[n_ready++] = k;      }   if (reorder(j, cursec, ihdlr, il, n_ready)) n_ready = 1;   for (n = 0; n < n_ready; n++) {      k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;      if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {         printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\                " busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"),                SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, k);         HD(j)->cp_stat[k] = ABORTING;         continue;         }      outl(V2DEV(cpp), sh[j]->io_port + REG_OGM);      outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR);      HD(j)->cp_stat[k] = IN_USE;      }}static inline void ihdlr(int irq, unsigned int j) {   Scsi_Cmnd *SCpnt;   unsigned int i, k, c, status, tstatus, reg, ret;   struct mscp *spp, *cpp;   if (sh[j]->irq != irq)       panic("%s: ihdlr, irq %d, sh[j]->irq %d.\n", BN(j), irq, sh[j]->irq);   /* Check if this board need to be serviced */   if (!((reg = inb(sh[j]->io_port + REG_SYS_INTR)) & IRQ_ASSERTED)) return;   HD(j)->iocount++;   if (do_trace) printk("%s: ihdlr, enter, irq %d, count %d.\n", BN(j), irq,                        HD(j)->iocount);   /* Check if this board is still busy */   if (wait_on_busy(sh[j]->io_port, 20 * MAXLOOP)) {      outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR);      printk("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",             BN(j), irq, reg, HD(j)->iocount);      return;      }   spp = (struct mscp *)DEV2V(ret = inl(sh[j]->io_port + REG_ICM));   cpp = spp;   /* Clear interrupt pending flag */   outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR);#if defined(DEBUG_GENERATE_ABORTS)   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) return;#endif   /* Find the mailbox to be serviced on this board */   i = cpp - HD(j)->cp;   if (cpp < HD(j)->cp || cpp >= HD(j)->cp + sh[j]->can_queue                                     || i >= sh[j]->can_queue)      panic("%s: ihdlr, invalid mscp bus address %p, cp0 %p.\n", BN(j),            (void *)ret, HD(j)->cp);   if (HD(j)->cp_stat[i] == IGNORE) {      HD(j)->cp_stat[i] = FREE;      return;      }   else if (HD(j)->cp_stat[i] == LOCKED) {      HD(j)->cp_stat[i] = FREE;      printk("%s: ihdlr, mbox %d unlocked, count %d.\n", BN(j), i,             HD(j)->iocount);      return;      }   else if (HD(j)->cp_stat[i] == FREE) {      printk("%s: ihdlr, mbox %d is free, count %d.\n", BN(j), i,             HD(j)->iocount);      return;      }   else if (HD(j)->cp_stat[i] == IN_RESET)      printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);   else if (HD(j)->cp_stat[i] != IN_USE)      panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n",            BN(j), i, HD(j)->cp_stat[i]);   HD(j)->cp_stat[i] = FREE;   SCpnt = cpp->SCpnt;   if (SCpnt == NULL) panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i);   if (SCpnt->host_scribble == NULL)      panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", BN(j), i,            SCpnt->pid, SCpnt);   if (*(unsigned int *)SCpnt->host_scribble != i)      panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n",            BN(j), i, SCpnt->pid, *(unsigned int *)SCpnt->host_scribble);   if (linked_comm && SCpnt->device->queue_depth > 2                                     && TLDEV(SCpnt->device->type))      flush_dev(SCpnt->device, SCpnt->request.sector, j, TRUE);   tstatus = status_byte(spp->target_status);#if defined(DEBUG_GENERATE_ERRORS)   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 200) < 2))                                           spp->adapter_status = 0x01;#endif   switch (spp->adapter_status) {      case ASOK:     /* status OK */         /* Forces a reset if a disk drive keeps returning BUSY */         if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE)            status = DID_ERROR << 16;         /* If there was a bus reset, redo operation on each target */         else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK                  && HD(j)->target_redo[SCpnt->target][SCpnt->channel])            status = DID_BUS_BUSY << 16;         /* Works around a flaw in scsi.c */         else if (tstatus == CHECK_CONDITION                  && SCpnt->device->type == TYPE_DISK                  && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)            status = DID_BUS_BUSY << 16;         else            status = DID_OK << 16;         if (tstatus == GOOD)            HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE;         if (spp->target_status && SCpnt->device->type == TYPE_DISK)            printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\                   "target_status 0x%x, sense key 0x%x.\n", BN(j),                   SCpnt->channel, SCpnt->target, SCpnt->lun,                   SCpnt->pid, spp->target_status,                   SCpnt->sense_buffer[2]);         HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0;         if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;         break;      case ASST:     /* Selection Time Out */         if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1)            status = DID_ERROR << 16;         else {            status = DID_TIME_OUT << 16;            HD(j)->target_to[SCpnt->target][SCpnt->channel]++;            }         break;      /* Perform a limited number of internal retries */      case 0x93:     /* Unexpected bus free */      case 0x94:     /* Target bus phase sequence failure */      case 0x96:     /* Illegal SCSI command */      case 0xa3:     /* SCSI bus reset error */         for (c = 0; c <= sh[j]->max_channel; c++)            for (k = 0; k < sh[j]->max_id; k++)               HD(j)->target_redo[k][c] = TRUE;      case 0x92:     /* Data over/under-run */         if (SCpnt->device->type != TYPE_TAPE             && HD(j)->retries < MAX_INTERNAL_RETRIES) {#if defined(DID_SOFT_ERROR)            status = DID_SOFT_ERROR << 16;#else            status = DID_BUS_BUSY << 16;#endif            HD(j)->retries++;            HD(j)->last_retried_pid = SCpnt->pid;            }         else            status = DID_ERROR << 16;         break;      case 0x01:     /* Invalid command */      case 0x02:     /* Invalid parameters */      case 0x03:     /* Invalid data list */      case 0x84:     /* SCSI bus abort error */      case 0x9b:     /* Auto request sense error */      case 0x9f:     /* Unexpected command complete message error */      case 0xff:     /* Invalid parameter in the S/G list */      default:         status = DID_ERROR << 16;         break;      }   SCpnt->result = status | spp->target_status;#if defined(DEBUG_INTERRUPT)   if (SCpnt->result || do_trace)#else   if ((spp->adapter_status != ASOK && HD(j)->iocount >  1000) ||       (spp->adapter_status != ASOK &&        spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||        do_trace || msg_byte(spp->target_status))#endif      printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\             " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n",             BN(j), i, spp->adapter_status, spp->target_status,             SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid,             reg, HD(j)->iocount);   /* Set the command state to inactive */   SCpnt->host_scribble = NULL;   SCpnt->scsi_done(SCpnt);   if (do_trace) printk("%s: ihdlr, exit, irq %d, count %d.\n", BN(j), irq,                        HD(j)->iocount);   return;}static void do_interrupt_handler(int irq, void *shap, struct pt_regs *regs) {   unsigned int j;   IRQ_FLAGS   SPIN_FLAGS   /* Check if the interrupt must be processed by this handler */   if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return;   SPIN_LOCK_SAVE   IRQ_LOCK_SAVE   ihdlr(irq, j);   IRQ_UNLOCK_RESTORE   SPIN_UNLOCK_RESTORE}int u14_34f_release(struct Scsi_Host *shpnt) {   unsigned int i, j;   IRQ_FLAGS   IRQ_LOCK_SAVE   f

⌨️ 快捷键说明

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