磁盘请求在处理时,切换进程

This commit is contained in:
fslongjin
2022-04-19 15:13:59 +08:00
parent 0e8bf69d65
commit 39dd802ff1
14 changed files with 257 additions and 206 deletions

View File

@ -1,9 +1,13 @@
#include "ahci.h"
#include "../../../common/kprint.h"
#include "../../../mm/slab.h"
#include <syscall/syscall.h>
#include <syscall/syscall_num.h>
struct pci_device_structure_header_t *ahci_devs[MAX_AHCI_DEVICES];
struct block_device_request_queue ahci_req_queue;
uint32_t count_ahci_devices = 0;
uint64_t ahci_port_base_vaddr; // 端口映射base addr
@ -27,20 +31,20 @@ void ahci_init()
{
kinfo("Initializing AHCI...");
pci_get_device_structure(0x1, 0x6, ahci_devs, &count_ahci_devices);
if (count_ahci_devices == 0)
{
kwarn("There is no AHCI device found on this computer!");
return;
}
// 映射ABAR
kdebug("phys_2_virt(ahci_devs[0])= %#018lx",(ahci_devs[0]));
kdebug("((struct pci_device_structure_general_device_t *)phys_2_virt(ahci_devs[0])))->BAR5= %#018lx",((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5);
kdebug("phys_2_virt(ahci_devs[0])= %#018lx", (ahci_devs[0]));
kdebug("((struct pci_device_structure_general_device_t *)phys_2_virt(ahci_devs[0])))->BAR5= %#018lx", ((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5);
uint32_t bar5 = ((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5;
mm_map_phys_addr(AHCI_MAPPING_BASE, (ul)(bar5) & PAGE_2M_MASK, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
mm_map_phys_addr(AHCI_MAPPING_BASE, (ul)(bar5)&PAGE_2M_MASK, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
kdebug("ABAR mapped!");
for (int i = 0; i < count_ahci_devices; ++i)
for (int i = 0; i < count_ahci_devices; ++i)
{
// kdebug("[%d] class_code=%d, sub_class=%d, progIF=%d, ABAR=%#010lx", i, ahci_devs[i]->Class_code, ahci_devs[i]->SubClass, ahci_devs[i]->ProgIF, ((struct pci_device_structure_general_device_t *)(ahci_devs[i]))->BAR5);
// 赋值HBA_MEM结构体
@ -54,10 +58,10 @@ void ahci_init()
kdebug("ahci_port_base_vaddr=%#018lx", ahci_port_base_vaddr);
ahci_probe_port(0);
port_rebase(&ahci_devices[0].hba_mem->ports[0], 0);
// 初始化请求队列
ahci_req_queue.in_service = NULL;
list_init(&(ahci_req_queue.queue_list));
wait_queue_init(&ahci_req_queue.wait_queue_list, NULL);
ahci_req_queue.request_count = 0;
kinfo("AHCI initialized.");
}
@ -278,6 +282,8 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t
kdebug("slot=%d", slot);
port->ci = 1 << slot; // Issue command
sched_cfs();
int retval = AHCI_SUCCESS;
// Wait for completion
while (1)
{
@ -288,7 +294,8 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t
if (port->is & HBA_PxIS_TFES) // Task file error
{
kerror("Read disk error");
return E_TASK_FILE_ERROR;
retval = E_TASK_FILE_ERROR;
break;
}
}
@ -296,10 +303,10 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t
if (port->is & HBA_PxIS_TFES)
{
kerror("Read disk error");
return E_TASK_FILE_ERROR;
retval = E_TASK_FILE_ERROR;
}
return AHCI_SUCCESS;
enter_syscall_int(SYS_AHCI_END_REQ, 0, 0, 0, 0, 0, 0, 0, 0);
return retval;
}
static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t count,
@ -352,6 +359,10 @@ static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_
cmdfis->counth = count >> 8;
// printk("[slot]{%d}", slot);
port->ci = 1; // Issue command
sched_cfs();
int retval = AHCI_SUCCESS;
while (1)
{
// In some longer duration reads, it may be helpful to spin on the DPS bit
@ -361,16 +372,18 @@ static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_
if (port->is & HBA_PxIS_TFES)
{ // Task file error
kerror("Write disk error");
return E_TASK_FILE_ERROR;
retval = E_TASK_FILE_ERROR;
break;
}
}
if (port->is & HBA_PxIS_TFES)
{
kerror("Write disk error");
return E_TASK_FILE_ERROR;
retval = E_TASK_FILE_ERROR;
}
return AHCI_SUCCESS;
enter_syscall_int(SYS_AHCI_END_REQ, 0, 0, 0, 0, 0, 0, 0, 0);
return retval;
}
// Find a free command list slot
@ -410,32 +423,33 @@ long ahci_close()
* @param port_num ahci控制器端口号
* @return struct block_device_request_packet*
*/
static struct block_device_request_packet *ahci_make_request(long cmd, uint64_t base_addr, uint64_t count, uint64_t buffer, uint8_t ahci_ctrl_num, uint8_t port_num)
static struct ahci_request_packet_t *ahci_make_request(long cmd, uint64_t base_addr, uint64_t count, uint64_t buffer, uint8_t ahci_ctrl_num, uint8_t port_num)
{
struct block_device_request_packet *pack = (struct block_device_request_packet *)kmalloc(sizeof(struct block_device_request_packet), 0);
struct ahci_request_packet_t *pack = (struct ahci_request_packet_t *)kmalloc(sizeof(struct ahci_request_packet_t), 0);
list_init(&pack->list);
wait_queue_init(&pack->blk_pak.wait_queue, current_pcb);
pack->blk_pak.device_type = BLK_TYPE_AHCI;
// 由于ahci不需要中断即可读取磁盘因此end handler为空
switch (cmd)
{
case ATA_CMD_READ_DMA_EXT:
pack->end_handler = NULL;
pack->cmd = ATA_CMD_READ_DMA_EXT;
pack->blk_pak.end_handler = NULL;
pack->blk_pak.cmd = ATA_CMD_READ_DMA_EXT;
break;
case ATA_CMD_WRITE_DMA_EXT:
pack->end_handler = NULL;
pack->cmd = ATA_CMD_WRITE_DMA_EXT;
pack->blk_pak.end_handler = NULL;
pack->blk_pak.cmd = ATA_CMD_WRITE_DMA_EXT;
break;
default:
pack->end_handler = NULL;
pack->cmd = cmd;
pack->blk_pak.end_handler = NULL;
pack->blk_pak.cmd = cmd;
break;
}
pack->LBA_start = base_addr;
pack->count = count;
pack->buffer_vaddr = buffer;
pack->blk_pak.LBA_start = base_addr;
pack->blk_pak.count = count;
pack->blk_pak.buffer_vaddr = buffer;
pack->ahci_ctrl_num = ahci_ctrl_num;
pack->port_num = port_num;
@ -446,8 +460,10 @@ static struct block_device_request_packet *ahci_make_request(long cmd, uint64_t
* @brief 结束磁盘请求
*
*/
static void ahci_end_request()
void ahci_end_request()
{
ahci_req_queue.in_service->wait_queue.pcb->state = PROC_RUNNING;
ahci_req_queue.in_service->wait_queue.pcb->flags |= PROC_NEED_SCHED;
kfree((uint64_t *)ahci_req_queue.in_service);
ahci_req_queue.in_service = NULL;
@ -458,27 +474,31 @@ static void ahci_end_request()
static long ahci_query_disk()
{
struct block_device_request_packet *pack = container_of(list_next(&ahci_req_queue.queue_list), struct block_device_request_packet, list);
ahci_req_queue.in_service = pack;
list_del(&(ahci_req_queue.in_service->list));
wait_queue_node_t *wait_queue_tmp = container_of(list_next(&ahci_req_queue.wait_queue_list.wait_list), wait_queue_node_t, wait_list);
struct ahci_request_packet_t *pack = (struct ahci_request_packet_t *)container_of(wait_queue_tmp, struct block_device_request_packet, wait_queue);
ahci_req_queue.in_service = (struct block_device_request_packet *)pack;
list_del(&(ahci_req_queue.in_service->wait_queue.wait_list));
--ahci_req_queue.request_count;
long ret_val;
switch (pack->cmd)
switch (pack->blk_pak.cmd)
{
case ATA_CMD_READ_DMA_EXT:
ret_val = ahci_read(&(ahci_devices[pack->ahci_ctrl_num].hba_mem->ports[pack->port_num]), pack->LBA_start & 0xFFFFFFFF, ((pack->LBA_start) >> 32) & 0xFFFFFFFF, pack->count, pack->buffer_vaddr);
ret_val = ahci_read(&(ahci_devices[pack->ahci_ctrl_num].hba_mem->ports[pack->port_num]), pack->blk_pak.LBA_start & 0xFFFFFFFF, ((pack->blk_pak.LBA_start) >> 32) & 0xFFFFFFFF, pack->blk_pak.count, pack->blk_pak.buffer_vaddr);
break;
case ATA_CMD_WRITE_DMA_EXT:
ret_val = ahci_write(&(ahci_devices[pack->ahci_ctrl_num].hba_mem->ports[pack->port_num]), pack->LBA_start & 0xFFFFFFFF, ((pack->LBA_start) >> 32) & 0xFFFFFFFF, pack->count, pack->buffer_vaddr);
ret_val = ahci_write(&(ahci_devices[pack->ahci_ctrl_num].hba_mem->ports[pack->port_num]), pack->blk_pak.LBA_start & 0xFFFFFFFF, ((pack->blk_pak.LBA_start) >> 32) & 0xFFFFFFFF, pack->blk_pak.count, pack->blk_pak.buffer_vaddr);
break;
default:
kerror("Unsupport ahci command: %#05lx", pack->cmd);
kerror("Unsupport ahci command: %#05lx", pack->blk_pak.cmd);
ret_val = E_UNSUPPORTED_CMD;
break;
}
ahci_end_request();
// ahci_end_request();
return ret_val;
}
@ -487,9 +507,9 @@ static long ahci_query_disk()
*
* @param pack
*/
static void ahci_submit(struct block_device_request_packet *pack)
static void ahci_submit(struct ahci_request_packet_t *pack)
{
list_append(&(ahci_req_queue.queue_list), &(pack->list));
list_append(&(ahci_req_queue.wait_queue_list.wait_list), &(pack->blk_pak.wait_queue.wait_list));
++ahci_req_queue.request_count;
if (ahci_req_queue.in_service == NULL) // 当前没有正在请求的io包立即执行磁盘请求
@ -509,7 +529,7 @@ static void ahci_submit(struct block_device_request_packet *pack)
*/
static long ahci_transfer(long cmd, uint64_t base_addr, uint64_t count, uint64_t buf, uint8_t ahci_ctrl_num, uint8_t port_num)
{
struct block_device_request_packet *pack = NULL;
struct ahci_request_packet_t *pack = NULL;
if (cmd == ATA_CMD_READ_DMA_EXT || cmd == ATA_CMD_WRITE_DMA_EXT)
{

View File

@ -6,16 +6,16 @@
/**
* @todo 加入io调度器当操作系统实现了多进程之后要加入这个
*
*
*/
#define AHCI_MAPPING_BASE SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE+AHCI_MAPPING_OFFSET
#define AHCI_MAPPING_BASE SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + AHCI_MAPPING_OFFSET
#define MAX_AHCI_DEVICES 100
#define HBA_PxCMD_ST 0x0001
#define HBA_PxCMD_FRE 0x0010
#define HBA_PxCMD_FR 0x4000
#define HBA_PxCMD_CR 0x8000
#define HBA_PxCMD_ST 0x0001
#define HBA_PxCMD_FRE 0x0010
#define HBA_PxCMD_FR 0x4000
#define HBA_PxCMD_CR 0x8000
#define ATA_DEV_BUSY 0x80
#define ATA_DEV_DRQ 0x08
@ -23,11 +23,11 @@
#define ATA_CMD_READ_DMA_EXT 0x25
#define ATA_CMD_WRITE_DMA_EXT 0x30
#define HBA_PxIS_TFES (1 << 30) /* TFES - Task File Error Status */
#define HBA_PxIS_TFES (1 << 30) /* TFES - Task File Error Status */
#define AHCI_SUCCESS 0 // 请求成功
#define E_NOEMPTYSLOT 1 // 没有空闲的slot
#define E_PORT_HUNG 2 // 端口被挂起
#define AHCI_SUCCESS 0 // 请求成功
#define E_NOEMPTYSLOT 1 // 没有空闲的slot
#define E_PORT_HUNG 2 // 端口被挂起
#define E_TASK_FILE_ERROR 3 // 任务文件错误
#define E_UNSUPPORTED_CMD 4 // 不支持的命令
@ -210,169 +210,164 @@ typedef struct tagFIS_DMA_SETUP
typedef volatile struct tagHBA_PORT
{
uint64_t clb; // 0x00, command list base address, 1K-byte aligned
uint64_t fb; // 0x08, FIS base address, 256-byte aligned
uint32_t is; // 0x10, interrupt status
uint32_t ie; // 0x14, interrupt enable
uint32_t cmd; // 0x18, command and status
uint32_t rsv0; // 0x1C, Reserved
uint32_t tfd; // 0x20, task file data
uint32_t sig; // 0x24, signature
uint32_t ssts; // 0x28, SATA status (SCR0:SStatus)
uint32_t sctl; // 0x2C, SATA control (SCR2:SControl)
uint32_t serr; // 0x30, SATA error (SCR1:SError)
uint32_t sact; // 0x34, SATA active (SCR3:SActive)
uint32_t ci; // 0x38, command issue
uint32_t sntf; // 0x3C, SATA notification (SCR4:SNotification)
uint32_t fbs; // 0x40, FIS-based switch control
uint32_t rsv1[11]; // 0x44 ~ 0x6F, Reserved
uint32_t vendor[4]; // 0x70 ~ 0x7F, vendor specific
uint64_t clb; // 0x00, command list base address, 1K-byte aligned
uint64_t fb; // 0x08, FIS base address, 256-byte aligned
uint32_t is; // 0x10, interrupt status
uint32_t ie; // 0x14, interrupt enable
uint32_t cmd; // 0x18, command and status
uint32_t rsv0; // 0x1C, Reserved
uint32_t tfd; // 0x20, task file data
uint32_t sig; // 0x24, signature
uint32_t ssts; // 0x28, SATA status (SCR0:SStatus)
uint32_t sctl; // 0x2C, SATA control (SCR2:SControl)
uint32_t serr; // 0x30, SATA error (SCR1:SError)
uint32_t sact; // 0x34, SATA active (SCR3:SActive)
uint32_t ci; // 0x38, command issue
uint32_t sntf; // 0x3C, SATA notification (SCR4:SNotification)
uint32_t fbs; // 0x40, FIS-based switch control
uint32_t rsv1[11]; // 0x44 ~ 0x6F, Reserved
uint32_t vendor[4]; // 0x70 ~ 0x7F, vendor specific
} HBA_PORT;
typedef volatile struct tagHBA_MEM
{
// 0x00 - 0x2B, Generic Host Control
uint32_t cap; // 0x00, Host capability
uint32_t ghc; // 0x04, Global host control
uint32_t is; // 0x08, Interrupt status
uint32_t pi; // 0x0C, Port implemented
uint32_t vs; // 0x10, Version
uint32_t ccc_ctl; // 0x14, Command completion coalescing control
uint32_t ccc_pts; // 0x18, Command completion coalescing ports
uint32_t em_loc; // 0x1C, Enclosure management location
uint32_t em_ctl; // 0x20, Enclosure management control
uint32_t cap2; // 0x24, Host capabilities extended
uint32_t bohc; // 0x28, BIOS/OS handoff control and status
// 0x2C - 0x9F, Reserved
uint8_t rsv[0xA0-0x2C];
// 0xA0 - 0xFF, Vendor specific registers
uint8_t vendor[0x100-0xA0];
// 0x100 - 0x10FF, Port control registers
HBA_PORT ports[32]; // 1 ~ 32
// 0x00 - 0x2B, Generic Host Control
uint32_t cap; // 0x00, Host capability
uint32_t ghc; // 0x04, Global host control
uint32_t is; // 0x08, Interrupt status
uint32_t pi; // 0x0C, Port implemented
uint32_t vs; // 0x10, Version
uint32_t ccc_ctl; // 0x14, Command completion coalescing control
uint32_t ccc_pts; // 0x18, Command completion coalescing ports
uint32_t em_loc; // 0x1C, Enclosure management location
uint32_t em_ctl; // 0x20, Enclosure management control
uint32_t cap2; // 0x24, Host capabilities extended
uint32_t bohc; // 0x28, BIOS/OS handoff control and status
// 0x2C - 0x9F, Reserved
uint8_t rsv[0xA0 - 0x2C];
// 0xA0 - 0xFF, Vendor specific registers
uint8_t vendor[0x100 - 0xA0];
// 0x100 - 0x10FF, Port control registers
HBA_PORT ports[32]; // 1 ~ 32
} HBA_MEM;
// There are four kinds of FIS which may be sent to the host by the device as indicated in the following structure declaration.
//
//
typedef volatile struct tagHBA_FIS
{
// 0x00
FIS_DMA_SETUP dsfis; // DMA Setup FIS
uint8_t pad0[4];
// 0x20
FIS_PIO_SETUP psfis; // PIO Setup FIS
uint8_t pad1[12];
// 0x40
FIS_REG_D2H rfis; // Register Device to Host FIS
uint8_t pad2[4];
// 0x58
//FIS_DEV_BITS sdbfis; // Set Device Bit FIS
// 0x60
uint8_t ufis[64];
// 0xA0
uint8_t rsv[0x100-0xA0];
// 0x00
FIS_DMA_SETUP dsfis; // DMA Setup FIS
uint8_t pad0[4];
// 0x20
FIS_PIO_SETUP psfis; // PIO Setup FIS
uint8_t pad1[12];
// 0x40
FIS_REG_D2H rfis; // Register Device to Host FIS
uint8_t pad2[4];
// 0x58
// FIS_DEV_BITS sdbfis; // Set Device Bit FIS
// 0x60
uint8_t ufis[64];
// 0xA0
uint8_t rsv[0x100 - 0xA0];
} HBA_FIS;
typedef struct tagHBA_CMD_HEADER
{
// DW0
uint8_t cfl:5; // Command FIS length in DWORDS, 2 ~ 16
uint8_t a:1; // ATAPI
uint8_t w:1; // Write, 1: H2D, 0: D2H
uint8_t p:1; // Prefetchable
uint8_t r:1; // Reset
uint8_t b:1; // BIST
uint8_t c:1; // Clear busy upon R_OK
uint8_t rsv0:1; // Reserved
uint8_t pmp:4; // Port multiplier port
uint16_t prdtl; // Physical region descriptor table length in entries
// DW1
volatile
uint32_t prdbc; // Physical region descriptor byte count transferred
// DW2, 3
uint64_t ctba; // Command table descriptor base address
// DW4 - 7
uint32_t rsv1[4]; // Reserved
// DW0
uint8_t cfl : 5; // Command FIS length in DWORDS, 2 ~ 16
uint8_t a : 1; // ATAPI
uint8_t w : 1; // Write, 1: H2D, 0: D2H
uint8_t p : 1; // Prefetchable
uint8_t r : 1; // Reset
uint8_t b : 1; // BIST
uint8_t c : 1; // Clear busy upon R_OK
uint8_t rsv0 : 1; // Reserved
uint8_t pmp : 4; // Port multiplier port
uint16_t prdtl; // Physical region descriptor table length in entries
// DW1
volatile uint32_t prdbc; // Physical region descriptor byte count transferred
// DW2, 3
uint64_t ctba; // Command table descriptor base address
// DW4 - 7
uint32_t rsv1[4]; // Reserved
} HBA_CMD_HEADER;
typedef struct tagHBA_PRDT_ENTRY
{
uint64_t dba; // Data base address
uint32_t rsv0; // Reserved
// DW3
uint32_t dbc:22; // Byte count, 4M max
uint32_t rsv1:9; // Reserved
uint32_t i:1; // Interrupt on completion
} HBA_PRDT_ENTRY;
uint64_t dba; // Data base address
uint32_t rsv0; // Reserved
// DW3
uint32_t dbc : 22; // Byte count, 4M max
uint32_t rsv1 : 9; // Reserved
uint32_t i : 1; // Interrupt on completion
} HBA_PRDT_ENTRY;
typedef struct tagHBA_CMD_TBL
{
// 0x00
uint8_t cfis[64]; // Command FIS
// 0x40
uint8_t acmd[16]; // ATAPI command, 12 or 16 bytes
// 0x50
uint8_t rsv[48]; // Reserved
// 0x80
HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535
// 0x00
uint8_t cfis[64]; // Command FIS
// 0x40
uint8_t acmd[16]; // ATAPI command, 12 or 16 bytes
// 0x50
uint8_t rsv[48]; // Reserved
// 0x80
HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535
} HBA_CMD_TBL;
struct ahci_device_t
{
uint32_t type; // 设备类型
struct pci_device_structure_header_t * dev_struct;
HBA_MEM * hba_mem;
}ahci_devices[MAX_AHCI_DEVICES];
uint32_t type; // 设备类型
struct pci_device_structure_header_t *dev_struct;
HBA_MEM *hba_mem;
} ahci_devices[MAX_AHCI_DEVICES];
#define SATA_SIG_ATA 0x00000101 // SATA drive
#define SATA_SIG_ATAPI 0xEB140101 // SATAPI drive
#define SATA_SIG_SEMB 0xC33C0101 // Enclosure management bridge
#define SATA_SIG_PM 0x96690101 // Port multiplier
#define SATA_SIG_ATA 0x00000101 // SATA drive
#define SATA_SIG_ATAPI 0xEB140101 // SATAPI drive
#define SATA_SIG_SEMB 0xC33C0101 // Enclosure management bridge
#define SATA_SIG_PM 0x96690101 // Port multiplier
#define AHCI_DEV_NULL 0
#define AHCI_DEV_SATA 1
#define AHCI_DEV_SEMB 2
#define AHCI_DEV_PM 3
#define AHCI_DEV_SATAPI 4
#define HBA_PORT_IPM_ACTIVE 1
#define HBA_PORT_DET_PRESENT 3
struct block_device_request_queue ahci_req_queue;
struct ahci_request_packet_t
{
struct block_device_request_packet blk_pak; // 块设备请求包
uint8_t ahci_ctrl_num; // ahci控制器号 默认应为0
uint8_t port_num; // ahci的设备端口号
};
/**
* @brief 初始化ahci模块
*
*
*/
void ahci_init();
/**
* @brief 检测端口连接的设备的类型
*
*
* @param device_num ahci设备号
*/
static void ahci_probe_port(const uint32_t device_num);
@ -402,4 +397,6 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t
* @return false failed
*/
static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t count,
uint64_t buf);
uint64_t buf);
void ahci_end_request();

View File

@ -2,7 +2,9 @@
#include "../../common/glib.h"
#include "stdint.h"
#include <process/semaphore.h>
#define BLK_TYPE_AHCI 0
struct block_device_operation
{
long (*open)();
@ -22,11 +24,10 @@ struct block_device_request_packet
uint32_t count;
uint64_t buffer_vaddr;
uint8_t ahci_ctrl_num; // ahci控制器号, 默认应为0
uint8_t port_num; // ahci的设备端口号
uint8_t device_type; // 0: ahci
void (*end_handler)(ul num, ul arg);
struct List list;
wait_queue_node_t wait_queue;
};
/**
@ -35,7 +36,7 @@ struct block_device_request_packet
*/
struct block_device_request_queue
{
struct List queue_list;
wait_queue_node_t wait_queue_list;
struct block_device_request_packet * in_service; // 正在请求的结点
ul request_count;
};