📄 gdth_proc.c
字号:
id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ); if (id == -1) return(-EBUSY); piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum]; for (i = k = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) { found = FALSE; for (j = 0; j < ha->bus_cnt; ++j) { for (k = 0; k < MAXID; ++k) { if (ha->id[j][k].type == CACHE_DTYP && ha->id[j][k].hostdrive == piowr->iu.lockdrv.drives[i]) { found = TRUE; break; } } if (found) break; } if (!found) continue; if (piowr->iu.lockdrv.lock) { save_flags( flags ); cli(); ha->id[j][k].lock = 1; restore_flags( flags ); gdth_wait_completion( hanum, j, k ); gdth_stop_timeout( hanum, j, k ); } else { save_flags( flags ); cli(); ha->id[j][k].lock = 0; restore_flags( flags ); gdth_start_timeout( hanum, j, k ); gdth_next( hanum ); } } piord->size = sizeof(gdth_iord_str); piord->status = S_OK; break; case GDTIOCTL_LOCKCHN: id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ); if (id == -1) return(-EBUSY); for (k = 0, j = piowr->iu.lockchn.channel; k < MAXID; ++k) { if (ha->id[j][k].type != RAW_DTYP) continue; if (piowr->iu.lockchn.lock) { save_flags( flags ); cli(); ha->id[j][k].lock = 1; restore_flags( flags ); gdth_wait_completion( hanum, j, k ); gdth_stop_timeout( hanum, j, k ); } else { save_flags( flags ); cli(); ha->id[j][k].lock = 0; restore_flags( flags ); gdth_start_timeout( hanum, j, k ); gdth_next( hanum ); } } piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum]; piord->size = sizeof(gdth_iord_str); piord->status = S_OK; break; case GDTIOCTL_EVENT: id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ); if (id == -1) return(-EBUSY); piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum]; if (piowr->iu.event.erase == 0) { piord->iu.event.handle = gdth_read_event( piowr->iu.event.handle, (gdth_evt_str *)piord->iu.event.evt ); } else { piord->iu.event.handle = piowr->iu.event.handle; gdth_readapp_event( (unchar)piowr->iu.event.erase, (gdth_evt_str *)piord->iu.event.evt ); } piord->size = sizeof(gdth_iord_str); piord->status = S_OK; break; default: return(-EINVAL); } /* we return a buffer ID to detect the right buffer during READ-IOCTL */ return id;}static int gdth_get_info(char *buffer,char **start,off_t offset, int length,int vh,int hanum,int busnum){ int size = 0,len = 0; off_t begin = 0,pos = 0; gdth_ha_str *ha; gdth_iord_str *piord; int id; TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum)); ha = HADATA(gdth_ctr_tab[hanum]); id = length; /* look for buffer ID in length */ if (id > 4) {#if LINUX_VERSION_CODE >= 0x020000 size = sprintf(buffer+len, "%s SCSI Disk Array Controller\n", ha->ctr_name);#else size = sprintf(buffer+len, "%s SCSI Disk Array Controller (SCSI Bus %d)\n", ha->ctr_name,busnum);#endif len += size; pos = begin + len; size = sprintf(buffer+len, "Firmware Version: %d.%2d\tDriver Version: %s\n", (unchar)(ha->cpar.version>>8), (unchar)(ha->cpar.version),GDTH_VERSION_STR); len += size; pos = begin + len; if (pos < offset) { len = 0; begin = pos; } if (pos > offset + length) goto stop_output; } else { piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum]; if (piord == NULL) goto stop_output; length = piord->size; memcpy(buffer+len, (char *)piord, length); gdth_ioctl_free(hanum, id); len += length; pos = begin + len; if (pos < offset) { len = 0; begin = pos; } if (pos > offset + length) goto stop_output; }stop_output: *start = buffer +(offset-begin); len -= (offset-begin); if (len > length) len = length; TRACE2(("get_info() len %d pos %d begin %d offset %d length %d size %d\n", len,(int)pos,(int)begin,(int)offset,length,size)); return(len);}void gdth_scsi_done(Scsi_Cmnd *scp){ TRACE2(("gdth_scsi_done()\n")); scp->request.rq_status = RQ_SCSI_DONE; if (scp->request.sem != NULL) up(scp->request.sem);}static int gdth_ioctl_alloc(int hanum, ushort size){ ulong flags; int i; if (size == 0) return -1; save_flags(flags); cli(); for (i = 0; i < 4; ++i) { if (gdth_ioctl_tab[i][hanum] == NULL) { gdth_ioctl_tab[i][hanum] = kmalloc( size, GFP_ATOMIC | GFP_DMA ); break; } } restore_flags(flags); if (i == 4 || gdth_ioctl_tab[i][hanum] == NULL) return -1; return (i+1);}static void gdth_ioctl_free(int hanum, int idx){ ulong flags; save_flags(flags); cli(); kfree( gdth_ioctl_tab[idx-1][hanum] ); gdth_ioctl_tab[idx-1][hanum] = NULL; restore_flags(flags);}static void gdth_wait_completion(int hanum, int busnum, int id){ ulong flags; int i; Scsi_Cmnd *scp; save_flags(flags); cli(); for (i = 0; i < GDTH_MAXCMDS; ++i) { scp = gdth_cmd_tab[i][hanum].cmnd;#if LINUX_VERSION_CODE >= 0x020000 if (!SPECIAL_SCP(scp) && scp->target == (unchar)id && scp->channel == (unchar)busnum)#else if (!SPECIAL_SCP(scp) && scp->target == (unchar)id && NUMDATA(scp->host)->busnum == (unchar)busnum)#endif { scp->SCp.have_data_in = 0; restore_flags(flags); while (!scp->SCp.have_data_in) barrier(); scp->scsi_done(scp); save_flags(flags); cli(); } } restore_flags(flags);}static void gdth_stop_timeout(int hanum, int busnum, int id){ ulong flags; Scsi_Cmnd *scp; gdth_ha_str *ha; save_flags(flags); cli(); ha = HADATA(gdth_ctr_tab[hanum]); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {#if LINUX_VERSION_CODE >= 0x020000 if (scp->target == (unchar)id && scp->channel == (unchar)busnum)#else if (scp->target == (unchar)id && NUMDATA(scp->host)->busnum == (unchar)busnum)#endif { TRACE2(("gdth_stop_timeout(): update_timeout()\n")); scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); } } restore_flags(flags);}static void gdth_start_timeout(int hanum, int busnum, int id){ ulong flags; Scsi_Cmnd *scp; gdth_ha_str *ha; save_flags(flags); cli(); ha = HADATA(gdth_ctr_tab[hanum]); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {#if LINUX_VERSION_CODE >= 0x020000 if (scp->target == (unchar)id && scp->channel == (unchar)busnum)#else if (scp->target == (unchar)id && NUMDATA(scp->host)->busnum == (unchar)busnum)#endif { TRACE2(("gdth_start_timeout(): update_timeout()\n")); gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual); } } restore_flags(flags);}static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout){ ulong flags; int oldto; save_flags(flags); cli(); oldto = scp->timeout_per_command; scp->timeout_per_command = timeout;#if LINUX_VERSION_CODE >= 0x02014B if (timeout == 0) { del_timer(&scp->eh_timeout); scp->eh_timeout.data = (unsigned long) NULL; scp->eh_timeout.expires = 0; } else { if (scp->eh_timeout.data != (unsigned long) NULL) del_timer(&scp->eh_timeout); scp->eh_timeout.data = (unsigned long) scp; scp->eh_timeout.expires = jiffies + timeout; add_timer(&scp->eh_timeout); }#else if (timeout > 0) { if (timer_table[SCSI_TIMER].expires == 0) { timer_table[SCSI_TIMER].expires = jiffies + timeout; timer_active |= 1 << SCSI_TIMER; } else { if (jiffies + timeout < timer_table[SCSI_TIMER].expires) timer_table[SCSI_TIMER].expires = jiffies + timeout; } }#endif restore_flags(flags); return oldto;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -