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

📄 gdth.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        return 0;    }    TRACE2(("gdth_search_drives() CACHES. init. after mountall\n"));    cdev_cnt = (ushort)ha->info;    /* detect number of buses - try new IOCTL */    iocr = (gdth_raw_iochan_str *)ha->pscratch;    iocr->hdr.version        = 0xffffffff;    iocr->hdr.list_entries   = MAXBUS;    iocr->hdr.first_chan     = 0;    iocr->hdr.last_chan      = MAXBUS-1;    iocr->hdr.list_offset    = GDTOFFSOF(gdth_raw_iochan_str, list[0]);    if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,IOCHAN_RAW_DESC,                          INVALID_CHANNEL,sizeof(gdth_raw_iochan_str))) {        TRACE2(("IOCHAN_RAW_DESC supported!\n"));        ha->bus_cnt = iocr->hdr.chan_count;        for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) {            if (iocr->list[bus_no].proc_id < MAXID)                ha->bus_id[bus_no] = iocr->list[bus_no].proc_id;            else                ha->bus_id[bus_no] = 0xff;        }    } else {        /* old method */        chn = (gdth_getch_str *)ha->pscratch;        for (bus_no = 0; bus_no < MAXBUS; ++bus_no) {            chn->channel_no = bus_no;            if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,                                   SCSI_CHAN_CNT | L_CTRL_PATTERN,                                   IO_CHANNEL | INVALID_CHANNEL,                                   sizeof(gdth_getch_str))) {                if (bus_no == 0) {                    printk("GDT: Error detecting channel count (0x%x)\n",                           ha->status);                    return 0;                }                break;            }            if (chn->siop_id < MAXID)                ha->bus_id[bus_no] = chn->siop_id;            else                ha->bus_id[bus_no] = 0xff;        }               ha->bus_cnt = (unchar)bus_no;    }    TRACE2(("gdth_search_drives() %d channels\n",ha->bus_cnt));    /* read cache configuration */    if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_INFO,                           INVALID_CHANNEL,sizeof(gdth_cinfo_str))) {        printk("GDT: Initialization error cache service (code %d)\n",               ha->status);        return 0;    }    ha->cpar = ((gdth_cinfo_str *)ha->pscratch)->cpar;    TRACE2(("gdth_search_drives() cinfo: vs %x sta %d str %d dw %d b %d\n",            ha->cpar.version,ha->cpar.state,ha->cpar.strategy,            ha->cpar.write_back,ha->cpar.block_size));    /* read board info and features */    ha->more_proc = FALSE;    if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,BOARD_INFO,                          INVALID_CHANNEL,sizeof(gdth_binfo_str))) {        memcpy(&ha->binfo, (gdth_binfo_str *)ha->pscratch, sizeof(gdth_binfo_str));        if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,BOARD_FEATURES,                              INVALID_CHANNEL,sizeof(gdth_bfeat_str))) {            TRACE2(("BOARD_INFO/BOARD_FEATURES supported\n"));            ha->bfeat = *(gdth_bfeat_str *)ha->pscratch;            ha->more_proc = TRUE;        }    } else {        TRACE2(("BOARD_INFO requires firmware >= 1.10/2.08\n"));        strcpy(ha->binfo.type_string, gdth_ctr_name(hanum));    }    TRACE2(("Controller name: %s\n",ha->binfo.type_string));    /* read more informations */    if (ha->more_proc) {        /* physical drives, channel addresses */        ioc = (gdth_iochan_str *)ha->pscratch;        ioc->hdr.version        = 0xffffffff;        ioc->hdr.list_entries   = MAXBUS;        ioc->hdr.first_chan     = 0;        ioc->hdr.last_chan      = MAXBUS-1;        ioc->hdr.list_offset    = GDTOFFSOF(gdth_iochan_str, list[0]);        if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,IOCHAN_DESC,                              INVALID_CHANNEL,sizeof(gdth_iochan_str))) {            for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) {                ha->raw[bus_no].address = ioc->list[bus_no].address;                ha->raw[bus_no].local_no = ioc->list[bus_no].local_no;            }        } else {            for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) {                ha->raw[bus_no].address = IO_CHANNEL;                ha->raw[bus_no].local_no = bus_no;            }        }        for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) {            chn = (gdth_getch_str *)ha->pscratch;            chn->channel_no = ha->raw[bus_no].local_no;            if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,                                  SCSI_CHAN_CNT | L_CTRL_PATTERN,                                  ha->raw[bus_no].address | INVALID_CHANNEL,                                  sizeof(gdth_getch_str))) {                ha->raw[bus_no].pdev_cnt = chn->drive_cnt;                TRACE2(("Channel %d: %d phys. drives\n",                        bus_no,chn->drive_cnt));            }            if (ha->raw[bus_no].pdev_cnt > 0) {                drl = (gdth_drlist_str *)ha->pscratch;                drl->sc_no = ha->raw[bus_no].local_no;                drl->sc_cnt = ha->raw[bus_no].pdev_cnt;                if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,                                      SCSI_DR_LIST | L_CTRL_PATTERN,                                      ha->raw[bus_no].address | INVALID_CHANNEL,                                      sizeof(gdth_drlist_str))) {                    for (j = 0; j < ha->raw[bus_no].pdev_cnt; ++j)                         ha->raw[bus_no].id_list[j] = drl->sc_list[j];                } else {                    ha->raw[bus_no].pdev_cnt = 0;                }            }        }        /* logical drives */        if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_DRV_CNT,                              INVALID_CHANNEL,sizeof(ulong32))) {            drv_cnt = *(ulong32 *)ha->pscratch;            if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_DRV_LIST,                                  INVALID_CHANNEL,drv_cnt * sizeof(ulong32))) {                for (j = 0; j < drv_cnt; ++j) {                    drv_no = ((ulong32 *)ha->pscratch)[j];                    if (drv_no < MAX_HDRIVES) {                        ha->hdr[drv_no].is_logdrv = TRUE;                        TRACE2(("Drive %d is log. drive\n",drv_no));                    }                }            }            if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,                                  ARRAY_DRV_LIST | LA_CTRL_PATTERN,                                  0, 35 * sizeof(gdth_arraylist_str))) {                for (j = 0; j < 35; ++j) {                    alst = &((gdth_arraylist_str *)ha->pscratch)[j];                    ha->hdr[j].is_arraydrv = alst->is_arrayd;                    ha->hdr[j].is_master = alst->is_master;                    ha->hdr[j].is_parity = alst->is_parity;                    ha->hdr[j].is_hotfix = alst->is_hotfix;                    ha->hdr[j].master_no = alst->cd_handle;                }            }        }    }                                             /* initialize raw service */    if (!gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_INIT,0,0,0)) {        printk("GDT: Initialization error raw service (code %d)\n",               ha->status);        return 0;    }    TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n"));    /* set/get features raw service (scatter/gather) */    ha->raw_feat = 0;    if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_SET_FEAT,SCATTER_GATHER,                          0,0)) {        TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n"));        if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_GET_FEAT,0,0,0)) {            TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n",                    ha->info));            ha->raw_feat = (ushort)ha->info;        }    }     /* set/get features cache service (equal to raw service) */    if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_SET_FEAT,0,                          SCATTER_GATHER,0)) {        TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n"));        if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_GET_FEAT,0,0,0)) {            TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n",                    ha->info));            ha->cache_feat = (ushort)ha->info;        }    }    /* reserve drives for raw service */    if (reserve_mode != 0) {        gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_RESERVE_ALL,                          reserve_mode == 1 ? 1 : 3, 0, 0);        TRACE2(("gdth_search_drives(): RESERVE_ALL code %d\n",                 ha->status));    }    for (i = 0; i < MAX_RES_ARGS; i += 4) {        if (reserve_list[i] == hanum && reserve_list[i+1] < ha->bus_cnt &&             reserve_list[i+2] < ha->tid_cnt && reserve_list[i+3] < MAXLUN) {            TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d lun %d\n",                    reserve_list[i], reserve_list[i+1],                    reserve_list[i+2], reserve_list[i+3]));            if (!gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_RESERVE,0,                                   reserve_list[i+1], reserve_list[i+2] |                                    (reserve_list[i+3] << 8))) {                printk("GDT: Error raw service (RESERVE, code %d)\n",                       ha->status);             }        }    }    /* scanning for cache devices */    for (i=0; i<cdev_cnt && i<MAX_HDRIVES; ++i) {        TRACE(("gdth_search_drives() cachedev. %d\n",i));        if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_INFO,i,0,0)) {            /* static relation between host drive number and Bus/ID */            TRACE(("gdth_search_dr() drive %d mapped to bus/id %d/%d\n",                   i,ha->bus_cnt,i));            ha->hdr[i].present = TRUE;            ha->hdr[i].size = ha->info;            /* evaluate mapping (sectors per head, heads per cylinder) */            ha->hdr[i].size &= ~SECS32;            if (ha->info2 == 0) {		gdth_eval_mapping(ha->hdr[i].size,&drv_cyls,&drv_hds,&drv_secs);            } else {                drv_hds = ha->info2 & 0xff;                drv_secs = (ha->info2 >> 8) & 0xff;                drv_cyls = ha->hdr[i].size /drv_hds/drv_secs;            }            ha->hdr[i].heads = (unchar)drv_hds;            ha->hdr[i].secs  = (unchar)drv_secs;            /* round size */            ha->hdr[i].size  = drv_cyls * drv_hds * drv_secs;            TRACE2(("gdth_search_dr() cdr. %d size %d hds %d scs %d\n",                   i,ha->hdr[i].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 %d\n",                       i,ha->info));                ha->hdr[i].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));    ha = HADATA(gdth_ctr_tab[hanum]);    GDTH_LOCK_HA(ha, flags);    scp->SCp.this_residual = (int)priority;    b = scp->channel;    t = scp->target;    if (priority >= DEFAULT_PRI) {        if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||            (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) {            TRACE2(("gdth_putq(): locked IO -> update_timeout()\n"));            scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);        }    }    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;    }    GDTH_UNLOCK_HA(ha, 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, firsttime;    unchar this_cmd, next_cmd;    ulong flags;    int cmd_index;    TRACE(("gdth_next() hanum %d\n",hanum));    ha = HADATA(gdth_ctr_tab[hanum]);    GDTH_LOCK_HA(ha, flags);    ha->cmd_cnt = ha->cmd_offs_dpmem = 0;    this_cmd = firsttime = TRUE;    next_cmd = gdth_polling ? FALSE: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;        b = nscp->channel;        t = nscp->target;        if (nscp->SCp.this_residual >= DEFAULT_PRI) {            if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||                (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock))                 continue;        }        if (firsttime) {            if (gdth_test_busy(hanum)) {        /* controller busy ? */                TRACE(("gdth_next() controller %d busy !\n",hanum));                if (!gdth_polling) {                    GDTH_UNLOCK_HA(ha, flags);                    return;                }                while (gdth_test_busy(hanum))                    gdth_delay(1);            }               firsttime = FALSE;        }        if (nscp->done != gdth_scsi_done)         {        if (nscp->SCp.phase == -1) {            nscp->SCp.phase = SCSIRAWSERVICE;           /* default: raw svc. */             if (nscp->cmnd[0] == TEST_UNIT_READY) {                TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n",                         b, t, nscp->lun));                /* TEST_UNIT_READY -> set scan mode */                if ((ha->scan_mode & 0x0f) == 0) {                    if (b == 0 && t == 0 && nscp->lun == 0) {                        ha->scan_mode |= 1;                        TRACE2(("Scan mode: 0x%x\n", ha->scan_mode));                    }                } els

⌨️ 快捷键说明

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