📄 scsi_lib.c.txt
字号:
any problems, send mails to lysindybear@sina.com.cn
相关文件
/drivers/scsi/sd.c
这个程序文件主要提供scsi驱动程序的统一接口,当上层的块设备驱动程序将request送下来以后,
他负责接收这些request并进行包装成scsi命令,然后选择相应的设备送下去。
这个就是接受从高层来的request队列的接口函数,也就是所有scsi层的开始
void scsi_request_fn(request_queue_t * q)
while (1 == 1) { //无限循环
req = blkdev_entry_next_request(&q->queue_head);//从request队列中取一个request
if (req->cmd == SPECIAL) { //如果request是特殊的,比如失败的request等
…… //分配scsi命令等处理
} else { //否则就是一个正常的request请求,也就是新来的
STpnt = scsi_get_request_dev(req);//从这个request中取出要送到的设备
…… //检查设备的有效性
SCpnt = scsi_allocate_device(SDpnt, FALSE, FALSE);//生成一个scsi命令
if (!SCpnt) {
atomic_dec(&SHpnt->host_busy);
break;
} //这里很重要,如果设备忙的话,可能分配不到scsi命令,就直接跳出
//循环,因为request并没有从队列中摘掉,所以这个request还是有机会
//被再次检索到,并分配scsi命令的
if (SCpnt->request.cmd != SPECIAL) { //如果是正常的scsi命令
if (!SDpnt->scsi_init_io_fn(SCpnt)) {
if (req->special != SCpnt)
__scsi_release_command(SCpnt);
atomic_dec(&SHpnt->host_busy);
break;
} //这里的init主要做的事情是进行scatter_list操作
if (!STpnt->init_command(SCpnt)) { //这里进行真正的初始化操作
…… //如果不成功,销毁这个request
}
scsi_init_cmd_errh(SCpnt); //初始化这个scsi命令的错误处理部分
atomic_inc(&SDpnt->device_busy);//相应设备的忙状态加一
blkdev_dequeue_request(req); //将request从队列中摘掉
if (req != &SCpnt->request && req != &SRpnt->sr_request ) {
blkdev_release_request(req);
}//可以释放掉request,因为request中的数据都复制到了scsi命令中了
scsi_dispatch_cmd(SCpnt); //发布这个scsi命令
}
从这个request中找到相应的scsi设备的模板,设备模板中就包含了各种各样的处理函数
struct Scsi_Device_Template *scsi_get_request_dev(struct request *req)
for (spnt = scsi_devicelist; spnt; spnt = spnt->next) { //循环查找scsi设备链
if (spnt->blk && spnt->major == major) { //如果找到了设备好一致的
return spnt; //返回给用户
}
}
…… //错误处理
这个函数是当一个scsi命令处理完毕以后,进行后面的收尾工作,
void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
int block_sectors)
char *to = bh_kmap_irq(req->bh, &flags);
memcpy(to, SCpnt->buffer, SCpnt->bufflen);//将数据复制到bh中去
bh_kunmap_irq(to, &flags);
scsi_free(SCpnt->buffer, SCpnt->bufflen); //释放request中的内存
SCpnt->buffer = NULL; //将scsi命令进行清理
……
SCpnt = __scsi_end_request(SCpnt, 1, good_sectors,result == 0,1);//完成这个request
…… //太复杂,不必细看
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -