bsg.c:
bsg_init: 注册bsg char device
bsg_register_queue: scsi driver在init的时候调用
调用bsg_minor_idr生成dev minor
初始化bsg_class_device
生成sysfs class_dev, 并创建kobj link
bsg_unregister_queue: register的逆操作
bsg_fops: 字符设备操作函数
bsg_ioctl:
SG_GET_COMMAND_Q/SG_SET_COMMAND_Q: 获取或者设置bsg device的 max_queue
留意这个定义: int __user *uarg = (int __user *) arg; 用户空间指针
SG_IO:处理sg_io_v4, map sg_io_v4到 request, 包括参数和buffer(如果是write类型, 还要生成一个read类型的next request), 同时map的时候调用blk_rq_map_user, 此时生成bio,然后调用blk_execute_rq将request插入queue, 并触发queue run,等待request完成, 然后调用 blk_complete_sgv4_hdr_rq转换request成sg_io_v4, 并copy 到user space。转换的时候(unmap), 会释放bio, 及request。
其他由scsi_cmd_ioctl处理,
bsg_get_device: 在bsg_dev_idx_hash中查找queue等于指定queue的bsg_device, 找到则返回该bsg_device, 若找不到, 调用bsg_add_device生成一个bsg_device, 设置它的queue为给定的queue, 并加入到bsg_dev_idx_hash(iminor(inode), 然后返回bsg_device.
bsg_open: 调用bsg_get_device, 并将返回的bsg_device赋给file->private_data
bsg_put_device: 执行与get相逆的动作。
bsg_kref_release_function: 调用bsg_class_device的release函数, 并减少其parent的引用计数
bsg_write/__bsg_write: 处理sg_io_v4多个的写请求,
由file得到bsg_device. 由bsg_device得到queue,
生成bc,
转化hdr到request
增加request到bc, 执行request
异步处理request end io, 唤醒done wait.
(
bsg_alloc_command:生成bsg cmd
bsg_add_command: 将map的request赋给bsg command, 并将bsg cmd加到bsg device的busy_list, 并执行blk_execute_rq_nowait(会调用bsg_rq_end_io),
bsg_free_command: 释放bc, 并唤醒wq_free(bsg_poll等待)
bsg_rq_end_io:将bsg cmd(bc)移到bsg device的done_list, 并唤醒wq_done(bsg_poll等待, 还有release device的时候等待, 另外读的时候是需要等待done的, 写不许要)
)
bsg_read:
bsg_set_block: 根据文件flag设置或者清楚bsg_device的block标志
调用__bsg_read
返回读数, 如出错, 返回是否有错
__bsg_read:
得到sg_io_v4命令个数
调用bsg_get_done_cmd/bsg_next_done_cmd从bd的done_list中得到一个bsg_command(如果当前没有, 且是block的, 那就等一个bc的唤醒)
调用blk_complete_sgv4_hdr_rq转换bc的request/bio到sg_io_v4(hdr), 并释放request/bio
copy bc hdr到user buffer
调用bsg_free_command free bsg_command,并唤醒wait free等待队列, 在poll时用
循环处理完所有个数的sg_io_v4
bsg_complete_all_commands:在release bsg的时候调用
调用bsg_io_schedule直到所有的bc处理完成(把自己加到wq_done等待队列)
然后循环调用bsg_get_done_cmd/blk_complete_sgv4_hdr_rq/bsg_free_command直到所有的bc都被discard
bsg_rq_end_io的最后也会唤醒wq_done
bsg-lib.c: 没发现调用者
bsg_remove_queue: 停止queue work,并处理它的所有request
调用blk_stop_queue停止queue work
调用blk_fetch_request取下request, 并把它加到queue的timeout list中
调用blk_end_request_all完成request
bsg_unregister_queue