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

📄 gdth.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
            for (b=0,t=0; b<ha->bus_cnt; ++b) {                for (t=0; t<MAXID; ++t) {                    if (ha->id[b][t].type == EMPTY_DTYP) {                        pos_found = TRUE;                        break;                    }                }                if (pos_found)                    break;            }            TRACE(("gdth_search_dr() drive %d free pos at bus/id %d/%d\n",                         i,b,t));            ha->id[b][t].type      = CACHE_DTYP;            ha->id[b][t].devtype   = 0;            ha->id[b][t].size      = ha->info;            ha->id[b][t].hostdrive = i;            /* evaluate mapping (sectors per head, heads per cylinder) */	    ha->id[b][t].size &= ~SECS32;	    if (ha->info2 == 0) {		drv_cyls = ha->id[b][t].size /HEADS/SECS;		if (drv_cyls <= MAXCYLS) {		    drv_hds = HEADS;		    drv_secs= SECS;		} else {                            /* too high for 64*32 */		    drv_cyls = ha->id[b][t].size /MEDHEADS/MEDSECS;		    if (drv_cyls <= MAXCYLS) {			drv_hds = MEDHEADS;			drv_secs= MEDSECS;		    } else {                        /* too high for 127*63 */			drv_cyls = ha->id[b][t].size /BIGHEADS/BIGSECS;			drv_hds = BIGHEADS;			drv_secs= BIGSECS;		    }		}            } else {		drv_hds = ha->info2 & 0xff;		drv_secs = (ha->info2 >> 8) & 0xff;		drv_cyls = ha->id[b][t].size /drv_hds/drv_secs;	    }            ha->id[b][t].heads = (unchar)drv_hds;            ha->id[b][t].secs  = (unchar)drv_secs;            /* round size */            ha->id[b][t].size  = drv_cyls * drv_hds * drv_secs;            TRACE2(("gdth_search_dr() cdr. %d size %ld hds %ld scs %ld\n",                   i,ha->id[b][t].size,drv_hds,drv_secs));                        /* get informations about device */            if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_DEVTYPE,i,                                  0,0)) {                TRACE(("gdth_search_dr() cache drive %d devtype %ld\n",                       i,ha->info));                ha->id[b][t].devtype = (ushort)ha->info;            }        }    }    TRACE(("gdth_search_drives() OK\n"));    return 1;}/* command queueing/sending functions */static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority){    register gdth_ha_str *ha;    register Scsi_Cmnd *pscp;    register Scsi_Cmnd *nscp;    ulong flags;    unchar b, t;    TRACE(("gdth_putq() priority %d\n",priority));    save_flags(flags);    cli();    ha = HADATA(gdth_ctr_tab[hanum]);    scp->SCp.this_residual = (int)priority;    gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6);#if LINUX_VERSION_CODE >= 0x020000    b = scp->channel;#else    b = NUMDATA(nscp->host)->busnum;#endif    t = scp->target;#if LINUX_VERSION_CODE >= 0x010300    if (priority >= DEFAULT_PRI && ha->id[b][t].lock) {        TRACE2(("gdth_putq(): locked IO -> update_timeout()\n"));        scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);    }#endif    if (ha->req_first==NULL) {        ha->req_first = scp;                    /* queue was empty */        scp->SCp.ptr = NULL;    } else {                                    /* queue not empty */        pscp = ha->req_first;        nscp = (Scsi_Cmnd *)pscp->SCp.ptr;        /* priority: 0-highest,..,0xff-lowest */        while (nscp && (unchar)nscp->SCp.this_residual <= priority) {            pscp = nscp;            nscp = (Scsi_Cmnd *)pscp->SCp.ptr;        }        pscp->SCp.ptr = (char *)scp;        scp->SCp.ptr  = (char *)nscp;    }    restore_flags(flags);#ifdef GDTH_STATISTICS    flags = 0;    for (nscp=ha->req_first; nscp; nscp=(Scsi_Cmnd*)nscp->SCp.ptr)        ++flags;    if (max_rq < flags) {        max_rq = flags;        TRACE3(("GDT: max_rq = %d\n",(ushort)max_rq));    }#endif}static void gdth_next(int hanum){    register gdth_ha_str *ha;    register Scsi_Cmnd *pscp;    register Scsi_Cmnd *nscp;    unchar b, t, next_cmd, firsttime;    ushort hdrive;    ulong flags;    int cmd_index;    TRACE(("gdth_next() hanum %d\n",hanum));    save_flags(flags);    cli();    ha = HADATA(gdth_ctr_tab[hanum]);    ha->cmd_cnt = ha->cmd_offs_dpmem = 0;    next_cmd = firsttime = TRUE;    cmd_index = 0;    for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) {        if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr)            pscp = (Scsi_Cmnd *)pscp->SCp.ptr;#if LINUX_VERSION_CODE >= 0x020000        b = nscp->channel;#else        b = NUMDATA(nscp->host)->busnum;#endif        t = nscp->target;        if (nscp->SCp.this_residual < DEFAULT_PRI || !ha->id[b][t].lock) {            if (firsttime) {                if (gdth_test_busy(hanum)) {        /* controller busy ? */                    TRACE(("gdth_next() controller %d busy !\n",hanum));                    if (!gdth_polling) {                        restore_flags(flags);                        return;                    }                    while (gdth_test_busy(hanum))                        gdth_delay(1);                }                firsttime = FALSE;            }#if LINUX_VERSION_CODE >= 0x010300            if (nscp->done == gdth_scsi_done) {                if (!(cmd_index=gdth_special_cmd(hanum,nscp,b)))                    next_cmd = FALSE;            } else#endif            if (ha->id[b][t].type != CACHE_DTYP) {                if (!(cmd_index=gdth_fill_raw_cmd(hanum,nscp,b)))                    next_cmd = FALSE;            } else {                hdrive = ha->id[b][t].hostdrive;                switch (nscp->cmnd[0]) {                  case TEST_UNIT_READY:                  case INQUIRY:                  case REQUEST_SENSE:                  case READ_CAPACITY:                  case VERIFY:                  case START_STOP:                  case MODE_SENSE:                    TRACE2(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0],                        nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3],                        nscp->cmnd[4],nscp->cmnd[5]));                        gdth_internal_cache_cmd(hanum,nscp,b,&flags);                    break;                  case ALLOW_MEDIUM_REMOVAL:                    TRACE2(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0],                        nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3],                        nscp->cmnd[4],nscp->cmnd[5]));                    if ( (nscp->cmnd[4]&1) && !(ha->id[b][t].devtype&1) ) {                        TRACE2(("Prevent r. nonremov. drive->do nothing\n"));                        nscp->result = DID_OK << 16;                        restore_flags( flags );                        if (!nscp->SCp.have_data_in)                            nscp->SCp.have_data_in++;                        else                            nscp->scsi_done(nscp);                        save_flags( flags );                        cli();                    } else {                        nscp->cmnd[3] = (ha->id[b][t].devtype&1) ? 1:0;                        TRACE2(("Prevent/allow r. %d rem. drive %d\n",                            nscp->cmnd[4],nscp->cmnd[3]));                        if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,hdrive)))                            next_cmd = FALSE;                    }                    break;                  case READ_6:                  case WRITE_6:                  case READ_10:                  case WRITE_10:                    if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,hdrive)))                        next_cmd = FALSE;                    break;                  default:                    TRACE2(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0],                        nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3],                        nscp->cmnd[4],nscp->cmnd[5]));                    printk("GDT: Unknown SCSI command 0x%x to cache service !\n",                       nscp->cmnd[0]);                    nscp->result = DID_ABORT << 16;                    restore_flags( flags );                    if (!nscp->SCp.have_data_in)                        nscp->SCp.have_data_in++;                    else                        nscp->scsi_done(nscp);                    save_flags( flags );                    cli();                    break;                }            }            if (!next_cmd)                break;            if (nscp == ha->req_first)                ha->req_first = pscp = (Scsi_Cmnd *)nscp->SCp.ptr;            else                pscp->SCp.ptr = nscp->SCp.ptr;            if (gdth_polling)                break;        }    }    if (ha->cmd_cnt > 0) {        gdth_release_event(hanum);    }    restore_flags(flags);    if (gdth_polling && ha->cmd_cnt > 0) {        if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT))            printk("GDT: Controller %d: Command %d timed out !\n",                   hanum,cmd_index);    }}    static void gdth_copy_internal_data(Scsi_Cmnd *scp,char *buffer,ushort count){    ushort cpcount,i;    ushort cpsum,cpnow;    struct scatterlist *sl;    cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen;    if (scp->use_sg) {        sl = (struct scatterlist *)scp->request_buffer;        for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) {            cpnow = (ushort)sl->length;            TRACE(("copy_internal() now %d sum %d count %d %d\n",                          cpnow,cpsum,cpcount,(ushort)scp->bufflen));            if (cpsum+cpnow > cpcount)                 cpnow = cpcount - cpsum;            cpsum += cpnow;            memcpy((char*)sl->address,buffer,cpnow);            if (cpsum == cpcount)                break;            buffer += cpnow;        }    } else {        TRACE(("copy_internal() count %d\n",cpcount));        memcpy((char*)scp->request_buffer,buffer,cpcount);    }}static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp,                                   unchar b,ulong *flags){    register gdth_ha_str *ha;    ushort hdrive;    unchar t;    gdth_inq_data inq;    gdth_rdcap_data rdc;    gdth_sense_data sd;    gdth_modep_data mpd;    ha = HADATA(gdth_ctr_tab[hanum]);    t  = scp->target;    hdrive = ha->id[b][t].hostdrive;    TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n",                 scp->cmnd[0],hdrive));    if (scp->lun !=0)        scp->result = DID_BAD_TARGET << 16;    else {        switch (scp->cmnd[0]) {          case TEST_UNIT_READY:          case VERIFY:          case START_STOP:            TRACE2(("Test/Verify/Start hdrive %d\n",hdrive));            break;          case INQUIRY:            TRACE2(("Inquiry hdrive %d devtype %d\n",                          hdrive,ha->id[b][t].devtype));            inq.type_qual = (ha->id[b][t].devtype&4) ? TYPE_ROM:TYPE_DISK;            /* you can here set all disks to removable, if you want to do               a flush using the ALLOW_MEDIUM_REMOVAL command */            inq.modif_rmb = ha->id[b][t].devtype&1 ? 0x80:0x00;            inq.version   = 2;            inq.resp_aenc = 2;            inq.add_length= 32;            strcpy(inq.vendor,"ICP    ");            sprintf(inq.product,"Host Drive  #%02d",hdrive);            strcpy(inq.revision,"   ");            gdth_copy_internal_data(scp,(char*)&inq,sizeof(gdth_inq_data));            break;          case REQUEST_SENSE:            TRACE2(("Request sense hdrive %d\n",hdrive));            sd.errorcode = 0x70;            sd.segno     = 0x00;            sd.key       = NO_SENSE;            sd.info      = 0;            sd.add_length= 0;            gdth_copy_internal_data(scp,(char*)&sd,sizeof(gdth_sense_data));            break;          case MODE_SENSE:            TRACE2(("Mode sense hdrive %d\n",hdrive));            memset((char*)&mpd,0,sizeof(gdth_modep_data));            mpd.hd.data_length = sizeof(gdth_modep_data);            mpd.hd.dev_par     = (ha->id[b][t].devtype&2) ? 0x80:0;            mpd.hd.bd_length   = sizeof(mpd.bd);            mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;            mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;            mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);            gdth_copy_internal_data(scp,(char*)&mpd,sizeof(gdth_modep_data));            break;          case READ_CAPACITY:            TRACE2(("Read capacity hdrive %d\n",hdrive));            rdc.last_block_no = ntohl(ha->id[b][t].size-1);            rdc.block_length  = ntohl(SECTOR_SIZE);            gdth_copy_internal_data(scp,(char*)&rdc,sizeof(gdth_rdcap_data));            break;          default:            TRACE2(("Internal cache cmd 0x%x unknown\n",scp->cmnd[0]));            break;        }        scp->result = DID_OK << 16;    }    restore_flags(*flags);    if (!scp->SCp.have_data_in)        scp->SCp.have_data_in++;    else        scp->scsi_done(scp);    save_flags(*flags);    cli();    return 1;}    static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive){    register gdth_ha_str *ha;    register gdth_cmd_str *cmdp;    struct scatterlist *sl;    ushort i;    int cmd_in

⌨️ 快捷键说明

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