9#include <ogc/disc_io.h>
13#include <ogc/usbstorage.h>
15#include "WiiUsbMulti.h"
16#include "../../Mutex.h"
20#define USB_CLASS_MASS_STORAGE 0x08
21#define USB_DEVLIST_MAXSIZE 8
22#define DEVICE_TYPE_WII_USB_MULTI (('W'<<24)|('U'<<16)|('S'<<8)|'M')
28 usbstorage_handle handle;
36 UsbSlot slots[WII_USB_MAX_DEVICES];
52 template<
int N>
bool Startup(DISC_INTERFACE *) {
MutexLock g(SlotLock());
return slots[N].open; }
53 template<
int N>
bool IsInserted(DISC_INTERFACE *) {
MutexLock g(SlotLock());
return slots[N].open; }
55 template<
int N>
bool ReadSectors(DISC_INTERFACE *, sec_t sector, sec_t numSectors,
void * buffer)
60 return USBStorage_Read(&slots[N].handle, slots[N].lun, sector, numSectors, (u8 *)buffer) >= 0;
63 template<
int N>
bool WriteSectors(DISC_INTERFACE *, sec_t sector, sec_t numSectors,
const void * buffer)
68 return USBStorage_Write(&slots[N].handle, slots[N].lun, sector, numSectors, (
const u8 *)buffer) >= 0;
71 template<
int N>
bool EraseSectors(DISC_INTERFACE *, sec_t, sec_t) {
return false; }
72 template<
int N>
bool Flush(DISC_INTERFACE *) {
return true; }
78 template<
int N>
bool Shutdown(DISC_INTERFACE *) {
return true; }
82 template<
int N>
void InitSlotInterface()
84 slots[N].disc = DISC_INTERFACE
86 DEVICE_TYPE_WII_USB_MULTI,
87 FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
101 bool SlotOpen(
int i, s32 deviceId, u16 vid, u16 pid)
103 UsbSlot & s = slots[i];
104 memset(&s.handle, 0,
sizeof(s.handle));
106 s32 openResult = USBStorage_Open(&s.handle, deviceId, vid, pid);
112 s32 maxLun = USBStorage_GetMaxLUN(&s.handle);
114 for(s32 lun = 0; lun < maxLun; lun++)
116 s32 retval = USBStorage_MountLUN(&s.handle, (u8)lun);
121 USBStorage_Reset(&s.handle);
126 s.deviceId = deviceId;
131 s.disc.numberOfSectors = s.handle.n_sectors[lun];
132 s.disc.bytesPerSector = s.handle.sector_size[lun];
136 USBStorage_Close(&s.handle);
141void WiiUsbMulti::init()
143 InitSlotInterface<0>();
144 InitSlotInterface<1>();
145 InitSlotInterface<2>();
147 for(
auto & s : slots)
155void WiiUsbMulti::shutdown()
159 for(
auto & s : slots)
162 USBStorage_Close(&s.handle);
167bool WiiUsbMulti::scan()
170 alignas(32) usb_device_entry buffer[USB_DEVLIST_MAXSIZE];
172 bool changed =
false;
176 if(USB_GetDeviceList(buffer, USB_DEVLIST_MAXSIZE, USB_CLASS_MASS_STORAGE, &deviceCount) < 0)
180 for(
auto & s : slots)
185 bool stillPresent =
false;
186 for(u8 j = 0; j < deviceCount; j++)
188 if(buffer[j].device_id == s.deviceId)
197 USBStorage_Close(&s.handle);
206 for(u8 j = 0; j < deviceCount; j++)
208 u16 vid = buffer[j].vid;
209 u16 pid = buffer[j].pid;
210 if(vid == 0 || pid == 0)
213 bool alreadyOpen =
false;
214 for(
auto & s : slots)
216 if(s.open && s.deviceId == buffer[j].device_id)
226 for(
int i = 0; i < WII_USB_MAX_DEVICES; i++)
237 if(SlotOpen(freeSlot, buffer[j].device_id, vid, pid))
244DISC_INTERFACE * WiiUsbMulti::getInterface(
int slot)
246 if(slot < 0 || slot >= WII_USB_MAX_DEVICES)
248 return &slots[slot].disc;
RAII lock guard - locks on construction, unlocks on destruction.
A simple mutual-exclusion lock.