📄 aha152x.c
字号:
setup[setup_count].io_port = aha152x[0]; setup[setup_count].irq = aha152x[1]; setup[setup_count].scsiid = aha152x[2]; setup[setup_count].reconnect = aha152x[3]; setup[setup_count].parity = aha152x[4]; setup[setup_count].synchronous = aha152x[5]; setup[setup_count].delay = aha152x[6]; setup[setup_count].ext_trans = aha152x[7];#if defined(AHA152X_DEBUG) setup[setup_count].debug = aha152x[8];#endif } else if(io[0]!=0 || irq[0]!=0) { if(io[0]!=0) setup[setup_count].io_port = io[0]; if(irq[0]!=0) setup[setup_count].irq = irq[0]; setup[setup_count].scsiid = scsiid[0]; setup[setup_count].reconnect = reconnect[0]; setup[setup_count].parity = parity[0]; setup[setup_count].synchronous = sync[0]; setup[setup_count].delay = delay[0]; setup[setup_count].ext_trans = exttrans[0];#if defined(AHA152X_DEBUG) setup[setup_count].debug = debug[0];#endif } if (checksetup(&setup[setup_count])) setup_count++; else printk(KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%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 || io[1]!=0 || irq[1]!=0)) { if(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];#if defined(AHA152X_DEBUG) setup[setup_count].debug = aha152x1[8];#endif } else if(io[1]!=0 || irq[1]!=0) { if(io[1]!=0) setup[setup_count].io_port = io[1]; if(irq[1]!=0) setup[setup_count].irq = irq[1]; setup[setup_count].scsiid = scsiid[1]; setup[setup_count].reconnect = reconnect[1]; setup[setup_count].parity = parity[1]; setup[setup_count].synchronous = sync[1]; setup[setup_count].delay = delay[1]; setup[setup_count].ext_trans = exttrans[1];#if defined(AHA152X_DEBUG) setup[setup_count].debug = debug[1];#endif } if (checksetup(&setup[setup_count])) setup_count++; else printk(KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%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 = isa_check_signature(addresses[i] + signatures[j].sig_offset, signatures[j].signature, signatures[j].sig_length); if (!ok && setup_count == 0) return 0; printk(KERN_INFO "aha152x: BIOS test: passed, ");#else printk(KERN_INFO "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]; setup[setup_count].tc1550 = 0; 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 = conf.cf_syncneg; setup[setup_count].delay = DELAY_DEFAULT; setup[setup_count].ext_trans = 0;#if defined(AHA152X_DEBUG) setup[setup_count].debug = DEBUG_DEFAULT;#endif setup_count++; } else if (tc1550_porttest(ports[i])) { ok++; setup[setup_count].io_port = ports[i]; setup[setup_count].tc1550 = 1; 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 = conf.cf_syncneg; setup[setup_count].delay = DELAY_DEFAULT; setup[setup_count].ext_trans = 0;#if defined(AHA152X_DEBUG) 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; aha152x_host[setup[i].irq - IRQ_MIN] = shpnt = scsi_register(tpnt, sizeof(struct aha152x_hostdata)); if(!shpnt) { printk(KERN_ERR "aha152x: scsi_register failed\n"); continue; } registered_count++; shpnt->io_port = setup[i].io_port; shpnt->n_io_port = IO_RANGE; shpnt->irq = setup[i].irq; if(!setup[i].tc1550) { HOSTIOPORT0 = setup[i].io_port; HOSTIOPORT1 = setup[i].io_port; } else { HOSTIOPORT0 = setup[i].io_port+0x10; HOSTIOPORT1 = setup[i].io_port-0x10; } ISSUE_SC = 0; CURRENT_SC = 0; DONE_SC = 0; DISCONNECTED_SC = 0; QLOCK = SPIN_LOCK_UNLOCKED; STATE = 0; PREVSTATE = 0; LASTSTATE = 0; MSGILEN = 0; MSGOLEN = 0; RECONNECT = setup[i].reconnect; SYNCHRONOUS = setup[i].synchronous; PARITY = setup[i].parity; DELAY = setup[i].delay; EXT_TRANS = setup[i].ext_trans;#if defined(AHA152X_DEBUG) HOSTDATA(shpnt)->debug = setup[i].debug;#endif HOSTDATA(shpnt)->in_intr = 0; HOSTDATA(shpnt)->commands = 0;#if defined(AHA152X_STAT) HOSTDATA(shpnt)->total_commands=0; HOSTDATA(shpnt)->disconnections=0; HOSTDATA(shpnt)->busfree_without_any_action=0; HOSTDATA(shpnt)->busfree_without_old_command=0; HOSTDATA(shpnt)->busfree_without_new_command=0; HOSTDATA(shpnt)->busfree_without_done_command=0; HOSTDATA(shpnt)->busfree_with_check_condition=0; for (j = idle; j<maxstate; j++) { HOSTDATA(shpnt)->count[j]=0; HOSTDATA(shpnt)->count_trans[j]=0; HOSTDATA(shpnt)->time[j]=0; }#endif for (j = 0; j < 8; j++) { HOSTDATA(shpnt)->syncrate[j] = 0; HOSTDATA(shpnt)->syncneg[j] = 0; } SETPORT(SCSIID, setup[i].scsiid << 4); shpnt->this_id = setup[i].scsiid; if (setup[i].reconnect) shpnt->can_queue = AHA152X_MAXQUEUE;#if 0 if(!shpnt->hostt->use_new_eh_code) {#endif /* RESET OUT */ printk("aha152x: resetting bus...\n"); SETPORT(SCSISEQ, SCSIRSTO); mdelay(256); SETPORT(SCSISEQ, 0); mdelay(DELAY);#if 0 }#endif reset_ports(shpnt); printk(KERN_INFO "aha152x%d%s: " "vital data: rev=%x, " "io=0x%03lx (0x%03lx/0x%03lx), " "irq=%d, " "scsiid=%d, " "reconnect=%s, " "parity=%s, " "synchronous=%s, " "delay=%d, " "extended translation=%s\n", HOSTNO, setup[i].tc1550 ? " (tc1550 mode)" : "", GETPORT(REV) & 0x7, shpnt->io_port, HOSTIOPORT0, HOSTIOPORT1, shpnt->irq, shpnt->this_id, RECONNECT ? "enabled" : "disabled", PARITY ? "enabled" : "disabled", SYNCHRONOUS ? "enabled" : "disabled", DELAY, EXT_TRANS ? "enabled" : "disabled"); request_region(shpnt->io_port, IO_RANGE, "aha152x"); /* not expecting any interrupts */ SETPORT(SIMODE0, 0); SETPORT(SIMODE1, 0); ok = request_irq(shpnt->irq, swintr, SA_INTERRUPT, "aha152x", shpnt); if (ok < 0) { if (ok==-EINVAL) printk(KERN_ERR "aha152x%d: bad IRQ %d.\n", HOSTNO, shpnt->irq); else if(ok==-EBUSY) printk(KERN_ERR "aha152x%d: IRQ %d already in use.\n", HOSTNO, shpnt->irq); else printk(KERN_ERR "aha152x%d: Unexpected error code %d on requesting IRQ %d.\n", HOSTNO, ok, shpnt->irq); printk(KERN_ERR "aha152x%d: driver needs an IRQ.\n", HOSTNO); scsi_unregister(shpnt); registered_count--; release_region(shpnt->io_port, IO_RANGE); aha152x_host[shpnt->irq - IRQ_MIN] = 0; shpnt = 0; continue; } HOSTDATA(shpnt)->swint = 0; printk(KERN_INFO "aha152x%d: trying software interrupt, ", HOSTNO); SETPORT(DMACNTRL0, SWINT|INTEN); spin_unlock_irq(&io_request_lock); mdelay(1000); spin_lock_irq(&io_request_lock); free_irq(shpnt->irq, shpnt); if (!HOSTDATA(shpnt)->swint) { if (TESTHI(DMASTAT, INTSTAT)) { printk("lost.\n"); } else { printk("failed.\n"); } printk(KERN_ERR "aha152x%d: IRQ %d possibly wrong. Please verify.\n", HOSTNO, shpnt->irq); registered_count--; release_region(shpnt->io_port, IO_RANGE); aha152x_host[shpnt->irq - IRQ_MIN] = 0; scsi_unregister(shpnt); shpnt=NULL; continue; } printk("ok.\n"); SETPORT(DMACNTRL0, INTEN); /* clear interrupts */ SETPORT(SSTAT0, 0x7f); SETPORT(SSTAT1, 0xef); if (request_irq(shpnt->irq, intr, SA_INTERRUPT, "aha152x", shpnt) < 0) { printk(KERN_ERR "aha152x%d: failed to reassign interrupt.\n", HOSTNO); scsi_unregister(shpnt); registered_count--; release_region(shpnt->io_port, IO_RANGE); shpnt = aha152x_host[shpnt->irq - IRQ_MIN] = 0; continue; } } return registered_count>0;}int aha152x_release(struct Scsi_Host *shpnt){ if (shpnt->irq) free_irq(shpnt->irq, shpnt); if (shpnt->io_port) release_region(shpnt->io_port, IO_RANGE); scsi_unregister(shpnt); return 0;}/* * setup controller to generate interrupts depending * on current state (lock has to be acquired) * */ static int setup_expected_interrupts(struct Scsi_Host *shpnt){ ASSERT_LOCK(&QLOCK,1); if(CURRENT_SC) { CURRENT_SC->SCp.phase |= 1 << 16; if(CURRENT_SC->SCp.phase & selecting) { DPRINTK(debug_intr, DEBUG_LEAD "expecting: (seldo) (seltimo) (seldi)\n", CMDINFO(CURRENT_SC)); SETPORT(SSTAT1, SELTO); SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0)); SETPORT(SIMODE1, ENSELTIMO); } else { DPRINTK(debug_intr, DEBUG_LEAD "expecting: (phase change) (busfree) %s\n", CMDINFO(CURRENT_SC), CURRENT_SC->SCp.phase & spiordy ? "(spiordy)" : ""); SETPORT(SIMODE0, (CURRENT_SC->SCp.phase & spiordy) ? ENSPIORDY : 0); SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE); } } else if(STATE==seldi) { DPRINTK(debug_intr, DEBUG_LEAD "expecting: (phase change) (identify)\n", CMDINFO(CURRENT_SC)); SETPORT(SIMODE0, 0); SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE); } else { DPRINTK(debug_intr, DEBUG_LEAD "expecting: %s %s\n", CMDINFO(CURRENT_SC), DISCONNECTED_SC ? "(reselection)" : "", ISSUE_SC ? "(busfree)" : ""); SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); SETPORT(SIMODE1, ENSCSIRST | ( (ISSUE_SC||DONE_SC) ? ENBUSFREE : 0)); } if(!HOSTDATA(shpnt)->in_intr) SETBITS(DMACNTRL0, INTEN); return TESTHI(DMASTAT, INTSTAT);}/* * Queue a command and setup interrupts for a free bus. */int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, Scsi_Cmnd *done_SC, void (*done)(Scsi_Cmnd *)){ struct Scsi_Host *shpnt = SCpnt->host; unsigned long flags;#if defined(AHA152X_DEBUG) if (HOSTDATA(shpnt)->debug & debug_queue) { printk(INFO_LEAD "queue: cmd_len=%d pieces=%d size=%u cmnd=", CMDINFO(SCpnt), SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen); print_command(SCpnt->cmnd); }#endif SCpnt->scsi_done = done; SCpnt->resid = SCpnt->request_bufflen; SCpnt->SCp.phase = not_issued | phase; SCpnt->SCp.Status = CHECK_CONDITION; SCpnt->SCp.Message = 0; SCpnt->SCp.have_data_in = 0; SCpnt->SCp.sent_command = 0; SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC); if(!SCpnt->host_scribble) { printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt)); return FAILED; } SCNEXT(SCpnt) = 0; SCDONE(SCpnt) = done_SC; SCSEM(SCpnt) = sem; /* 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 */ 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; } DO_LOCK(flags);#if defined(AHA152X_STAT) HOSTDATA(shpnt)->total_commands++;#endif /* Turn led on, when this is the first command. */ HOSTDATA(shpnt)->commands++; if (HOSTDATA(shpnt)->commands==1) SETPORT(PORTA, 1); append_SC(&ISSUE_SC, SCpnt); if(!HOSTDATA(shpnt)->in_intr) setup_expected_interrupts(shpnt); DO_UNLOCK(flags); return 0;}int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)){ if(*SCpnt->cmnd == REQUEST_SENSE) { SCpnt->result = 0; done(SCpnt); return SUCCESS; } return aha152x_internal_queue(SCpnt, 0, 0, 0, done);}/* * run a command * */void internal_done(Scsi_Cmnd *SCpnt){#if 0 struct Scsi_Host *shpnt = SCpnt->host; DPRINTK(debug_eh, INFO_LEAD "internal_done called\n", CMDINFO(SCpnt));#endif if(SCSEM(SCpnt)) up(SCSEM(SCpnt));}int aha152x_command(Scsi_Cmnd * SCpnt){ DECLARE_MUTEX_LOCKED(sem); aha152x_internal_queue(SCpnt, &sem, 0, 0, internal_done); down(&sem); return SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -