sh: maple: fix empty port handling
PATCH v2 1/1 sh: maple: fix empty port handling
Fix the handling of empty ports, to restore the ability to use the device with less than 4 populated ports and also be able to hot-plug new devices in empty ports at runtime.
Explicitly cast the response code in maple_response_devinfo() to s8 so that 0xFF from the device gets interpreted as signed and flows like the NONE response, previously it was considered unknown response code, which blocked the maple bus.
Remove the locking variable from maple_vblank_handler() as there is no locking information returned from maple_add_packet() and it lead to only ever check exactly one empty port.
Update maple_response_devinfo() to explicitly check for empty ports on unit 0, to be able to hot-plug devices in empty ports.
---v1->v2: Don't break hot-plugging of new devices to empty ports.
Explicitly cast the response code to s8 to use the existing logic, that relies on signed chars. In the case of 0xff (all 1s, DCs TIMEOUT response) that was interpreted as 255 unknown response code, which blocked the maple bus, as busy was never reset. Add condition to maple_response_devinfo() to process the devinfo for currently empty ports.
v1: https://lore.kernel.org/all/[email protected]/
Note that the removal of peripherals is possible, the ports get marked as empty, but the driver is never detached. That means a peripheral can be removed, but the port keeps "reserved" for this peripheral and can't be reused with another peripheral.
VMUs can't be removed at runtime, as MTD keeps a reference to it, so that mdev->can_unload() is never true. But the same peripheral can be inserted to the same port again.
drivers/sh/maple/maple.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
drivers/sh/maple/maple.c +6 -8
@@ -445,7 +445,7 @@ static int setup_maple_commands(struct device *device, void *ignored)/* VBLANK bottom half - implemented via workqueue */ static void maple_vblank_handler (struct work_struct *work) { -int x, locking; +int x;struct maple_device *mdev;if (!maple_dma_done ())
@@ -474,13 +474,10 @@ static void maple_vblank_handler(struct work_struct *work)if (!mdev)break ;atomic_set (&mdev->busy,1 ); - locking =maple_add_packet (mdev,0 , +maple_add_packet (mdev,0 ,MAPLE_COMMAND_DEVINFO ,0 ,NULL ); -if (!locking) -break ; - } } - + } maple_pnp_time = jiffies +MAPLE_PNP_INTERVAL ; }
@@ -578,7 +575,8 @@ static void maple_response_devinfo(struct maple_device *mdev, char *recvbuf) {char submask; -if (!started || (scanning ==2 ) || !fullscan) { +if (!started || (scanning ==2 ) || !fullscan || + ((mdev->unit ==0 ) && empty[mdev->port])) {if ((mdev->unit ==0 ) && (checked[mdev->port] == false)) { checked[mdev->port] = true;maple_attach_driver (mdev);
@@ -644,7 +642,7 @@ static void maple_dma_handler(struct work_struct *work) recvbuf = mq->recvbuf->buf;__flush_invalidate_region (sh_cacheop_vaddr (recvbuf),0x400 ); - code = recvbuf[0 ]; + code = (s8 )recvbuf[0 ];kfree (mq->sendbuf);list_del_init (&mq->list);switch (code) {
base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
Signature · 1 line
2.43.0
Quoted 9 lines · Florian Fuchs
Fix the handling of empty ports, to restore the ability to use the device with less than 4 populated ports and also be able to hot-plug new devices in empty ports at runtime.
Explicitly cast the response code in
maple_response_devinfo()to s8 so that0xFFfrom the device gets interpreted as signed and flows like the NONE response, previously it was considered unknown response code, which blocked the maple bus.
Quoted 8 lines
Remove the locking variable from
maple_vblank_handler()as there is no locking information returned frommaple_add_packet()and it lead to only ever check exactly one empty port.Update
maple_response_devinfo()to explicitly check for empty ports on unit 0, to be able to hot-plug devices in empty ports.Signed-off-by Florian Fuchs <[email protected]>
Hey Florian,
Commit message could be "massaged" a bit, but otherwise everything works fine. Thanks for fixing this!
Verified on real hardware.