Use a big-lock for kernel sychronization instead of fine-grained locking
All checks were successful
Build ISO image / build-and-deploy (push) Successful in 2m21s
Build documentation / build-and-deploy (push) Successful in 54s

This commit is contained in:
2026-04-27 18:06:02 +02:00
parent 68cdd8d6d2
commit e5ebd7f3ba
56 changed files with 212 additions and 1206 deletions

View File

@@ -27,35 +27,30 @@
#define SCSI_WRITE10 0x2A
static int usb_ms_send_cbw(struct xhci* xhci, struct xhci_usb_device* usb_device,
uint8_t bulk_out_endpoint, uintptr_t cbw_phys, uint64_t* lockflags) {
uint8_t bulk_out_endpoint, uintptr_t cbw_phys) {
return xhci_bulk_transfer(xhci, usb_device, bulk_out_endpoint, cbw_phys,
sizeof(struct usb_ms_cbw), lockflags);
sizeof(struct usb_ms_cbw));
}
static int usb_ms_read_data(struct xhci* xhci, struct xhci_usb_device* usb_device,
uint8_t bulk_in_endpoint, uintptr_t buffer_phys, size_t buffer_size,
uint64_t* lockflags) {
return xhci_bulk_transfer(xhci, usb_device, bulk_in_endpoint, buffer_phys, buffer_size,
lockflags);
uint8_t bulk_in_endpoint, uintptr_t buffer_phys, size_t buffer_size) {
return xhci_bulk_transfer(xhci, usb_device, bulk_in_endpoint, buffer_phys, buffer_size);
}
static int usb_ms_write_data(struct xhci* xhci, struct xhci_usb_device* usb_device,
uint8_t bulk_out_endpoint, uintptr_t buffer_phys, size_t buffer_size,
uint64_t* lockflags) {
return xhci_bulk_transfer(xhci, usb_device, bulk_out_endpoint, buffer_phys, buffer_size,
lockflags);
uint8_t bulk_out_endpoint, uintptr_t buffer_phys, size_t buffer_size) {
return xhci_bulk_transfer(xhci, usb_device, bulk_out_endpoint, buffer_phys, buffer_size);
}
static int usb_ms_read_csw(struct xhci* xhci, struct xhci_usb_device* usb_device,
uint8_t bulk_in_endpoint, uintptr_t csw_phys, uint64_t* lockflags) {
return xhci_bulk_transfer(xhci, usb_device, bulk_in_endpoint, csw_phys, sizeof(struct usb_ms_csw),
lockflags);
uint8_t bulk_in_endpoint, uintptr_t csw_phys) {
return xhci_bulk_transfer(xhci, usb_device, bulk_in_endpoint, csw_phys,
sizeof(struct usb_ms_csw));
}
static int usb_ms_scsi_read_capacity(struct xhci* xhci, struct xhci_usb_device* usb_device,
uint8_t bulk_in_endpoint, uint8_t bulk_out_endpoint,
size_t* sector_size, size_t* sector_count,
uint64_t* lockflags) {
size_t* sector_size, size_t* sector_count) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
int ret;
@@ -83,15 +78,15 @@ static int usb_ms_scsi_read_capacity(struct xhci* xhci, struct xhci_usb_device*
cbw->length = 8;
memcpy(cbw->data, cdb, sizeof(cdb));
if ((ret = usb_ms_send_cbw(xhci, usb_device, bulk_out_endpoint, cbw_phys, lockflags)) < 0) {
if ((ret = usb_ms_send_cbw(xhci, usb_device, bulk_out_endpoint, cbw_phys)) < 0) {
goto done;
}
if ((ret = usb_ms_read_data(xhci, usb_device, bulk_in_endpoint, data_phys, 8, lockflags)) < 0) {
if ((ret = usb_ms_read_data(xhci, usb_device, bulk_in_endpoint, data_phys, 8)) < 0) {
goto done;
}
if ((ret = usb_ms_read_csw(xhci, usb_device, bulk_in_endpoint, csw_phys, lockflags)) < 0) {
if ((ret = usb_ms_read_csw(xhci, usb_device, bulk_in_endpoint, csw_phys)) < 0) {
goto done;
}
@@ -118,8 +113,7 @@ done:
}
static int usb_ms_scsi_test_unit_ready(struct xhci* xhci, struct xhci_usb_device* usb_device,
uint8_t bulk_in_endpoint, uint8_t bulk_out_endpoint,
uint64_t* lockflags) {
uint8_t bulk_in_endpoint, uint8_t bulk_out_endpoint) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
int ret;
@@ -143,11 +137,11 @@ static int usb_ms_scsi_test_unit_ready(struct xhci* xhci, struct xhci_usb_device
cbw->length = 0;
memcpy(cbw->data, cdb, sizeof(cdb));
if ((ret = usb_ms_send_cbw(xhci, usb_device, bulk_out_endpoint, cbw_phys, lockflags)) < 0) {
if ((ret = usb_ms_send_cbw(xhci, usb_device, bulk_out_endpoint, cbw_phys)) < 0) {
goto done;
}
if ((ret = usb_ms_read_csw(xhci, usb_device, bulk_in_endpoint, csw_phys, lockflags)) < 0) {
if ((ret = usb_ms_read_csw(xhci, usb_device, bulk_in_endpoint, csw_phys)) < 0) {
goto done;
}
@@ -167,7 +161,7 @@ done:
static int usb_ms_scsi_read(struct xhci* xhci, struct xhci_usb_device* usb_device,
uint8_t bulk_in_endpoint, uint8_t bulk_out_endpoint,
uint8_t* out_buffer, uint32_t lba, uint16_t sector_count,
size_t sector_size, uint64_t* lockflags) {
size_t sector_size) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
int ret;
@@ -207,16 +201,16 @@ static int usb_ms_scsi_read(struct xhci* xhci, struct xhci_usb_device* usb_devic
cbw->length = sector_count * sector_size;
memcpy(cbw->data, cdb, sizeof(cdb));
if ((ret = usb_ms_send_cbw(xhci, usb_device, bulk_out_endpoint, cbw_phys, lockflags)) < 0) {
if ((ret = usb_ms_send_cbw(xhci, usb_device, bulk_out_endpoint, cbw_phys)) < 0) {
goto done;
}
if ((ret = usb_ms_read_data(xhci, usb_device, bulk_in_endpoint, data_phys,
sector_count * sector_size, lockflags)) < 0) {
sector_count * sector_size)) < 0) {
goto done;
}
if ((ret = usb_ms_read_csw(xhci, usb_device, bulk_in_endpoint, csw_phys, lockflags)) < 0) {
if ((ret = usb_ms_read_csw(xhci, usb_device, bulk_in_endpoint, csw_phys)) < 0) {
goto done;
}
@@ -240,7 +234,7 @@ done:
static int usb_ms_scsi_write(struct xhci* xhci, struct xhci_usb_device* usb_device,
uint8_t bulk_in_endpoint, uint8_t bulk_out_endpoint,
uint8_t* in_buffer, uint32_t lba, uint16_t sector_count,
size_t sector_size, uint64_t* lockflags) {
size_t sector_size) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
int ret;
@@ -277,16 +271,16 @@ static int usb_ms_scsi_write(struct xhci* xhci, struct xhci_usb_device* usb_devi
cbw->length = sector_count * sector_size;
memcpy(cbw->data, cdb, sizeof(cdb));
if ((ret = usb_ms_send_cbw(xhci, usb_device, bulk_out_endpoint, cbw_phys, lockflags)) < 0) {
if ((ret = usb_ms_send_cbw(xhci, usb_device, bulk_out_endpoint, cbw_phys)) < 0) {
goto done;
}
if ((ret = usb_ms_write_data(xhci, usb_device, bulk_out_endpoint, buffer_phys,
sector_count * sector_size, lockflags)) < 0) {
sector_count * sector_size)) < 0) {
goto done;
}
if ((ret = usb_ms_read_csw(xhci, usb_device, bulk_in_endpoint, csw_phys, lockflags)) < 0) {
if ((ret = usb_ms_read_csw(xhci, usb_device, bulk_in_endpoint, csw_phys)) < 0) {
goto done;
}
@@ -333,8 +327,6 @@ static void usbdrv_setup_endpoints(struct usbdrv* usbdrv) {
}
DEFINE_DEVICE_OP(usbdrv_read) {
uint64_t fd;
if (a1 == NULL || a2 == NULL || a3 == NULL)
return -ST_BAD_ADDRESS_SPACE;
@@ -344,24 +336,13 @@ DEFINE_DEVICE_OP(usbdrv_read) {
struct usbdrv* usbdrv = device->udata;
spin_unlock(&device->lock, *lockflags);
spin_lock(&usbdrv->xhci->device->lock, &fd);
spin_lock(&device->lock, lockflags);
int ret = usb_ms_scsi_read(usbdrv->xhci, usbdrv->usb_device, usbdrv->bulk_in.endpoint_addr,
usbdrv->bulk_out.endpoint_addr, buffer, sector, sector_count,
usbdrv->sector_size, &fd);
spin_unlock(&device->lock, *lockflags);
spin_unlock(&usbdrv->xhci->device->lock, fd);
spin_lock(&device->lock, lockflags);
usbdrv->sector_size);
return ret;
}
DEFINE_DEVICE_OP(usbdrv_write) {
uint64_t fd;
if (a1 == NULL || a2 == NULL || a3 == NULL)
return -ST_BAD_ADDRESS_SPACE;
@@ -371,18 +352,9 @@ DEFINE_DEVICE_OP(usbdrv_write) {
struct usbdrv* usbdrv = device->udata;
spin_unlock(&device->lock, *lockflags);
spin_lock(&usbdrv->xhci->device->lock, &fd);
spin_lock(&device->lock, lockflags);
int ret = usb_ms_scsi_write(usbdrv->xhci, usbdrv->usb_device, usbdrv->bulk_in.endpoint_addr,
usbdrv->bulk_out.endpoint_addr, buffer, sector, sector_count,
usbdrv->sector_size, &fd);
spin_unlock(&device->lock, *lockflags);
spin_unlock(&usbdrv->xhci->device->lock, fd);
spin_lock(&device->lock, lockflags);
usbdrv->sector_size);
return ret;
}
@@ -424,30 +396,21 @@ DEFINE_DEVICE_OP(usbdrv_get_size) {
}
DEFINE_DEVICE_OP(usbdrv_partition_rescan) {
uint64_t fsd;
struct list_node_link *subdevice_link, *tmp_subdevice_link;
list_foreach(device->subdevices, subdevice_link, tmp_subdevice_link) {
struct device* subdevice = list_entry(subdevice_link, struct device, subdevices_link);
spin_lock(&subdevice->lock, &fsd);
list_remove(device->subdevices, &subdevice->subdevices_link);
spin_unlock(&subdevice->lock, fsd);
device_delete(subdevice->key, proc, rctx);
}
spin_unlock(&device->lock, *lockflags);
int r = device_probe_partitions(proc, rctx, device);
spin_lock(&device->lock, lockflags);
return r;
}
DEFINE_DEVICE_INIT(usbdrv_init) {
uint64_t fd;
int ret;
struct usbdrv_init* init = arg;
@@ -462,39 +425,33 @@ DEFINE_DEVICE_INIT(usbdrv_init) {
device->udata = usbdrv;
spin_lock(&usbdrv->xhci->device->lock, &fd);
usbdrv_setup_endpoints(usbdrv);
ret = usb_ms_scsi_test_unit_ready(usbdrv->xhci, usbdrv->usb_device, usbdrv->bulk_in.endpoint_addr,
usbdrv->bulk_out.endpoint_addr, init->lockflags);
usbdrv->bulk_out.endpoint_addr);
if (ret < 0) {
stall_ms(100);
ret =
usb_ms_scsi_test_unit_ready(usbdrv->xhci, usbdrv->usb_device, usbdrv->bulk_in.endpoint_addr,
usbdrv->bulk_out.endpoint_addr, init->lockflags);
usbdrv->bulk_out.endpoint_addr);
}
if (ret < 0) {
spin_unlock(&usbdrv->xhci->device->lock, fd);
free(usbdrv);
return false;
}
ret = usb_ms_scsi_read_capacity(usbdrv->xhci, usbdrv->usb_device, usbdrv->bulk_in.endpoint_addr,
usbdrv->bulk_out.endpoint_addr, &usbdrv->sector_size,
&usbdrv->sector_count, init->lockflags);
&usbdrv->sector_count);
if (ret < 0) {
spin_unlock(&usbdrv->xhci->device->lock, fd);
free(usbdrv);
return false;
}
spin_unlock(&usbdrv->xhci->device->lock, fd);
DEBUG("sector_count = %zu, sector_size = %u\n", usbdrv->sector_count, usbdrv->sector_size);
return true;