Use a big-lock for kernel sychronization instead of fine-grained locking
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user