Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions src/Kernel/BlkDev/DiskAddDev.ZC
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ U0 BlkDevLockFwdingSet(CBlkDev *bd)
}
}

Bool BlkDevAddBlksRead(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
{//Partition-scan read during $LK,"BlkDevAdd",A="MN:BlkDevAdd"$(), before drive is validated.
if (bd->type == BDT_USB)
{
if (fp_usb_msd_blks_read)
return (*fp_usb_msd_blks_read)(bd, buf, blk, count);
return FALSE;
}
return AHCIAtaBlksRead(bd, buf, blk, count);
}

I64 BlkDevAdd(CBlkDev *bd, I64 prt_num=I64_MIN, Bool whole_drive, Bool make_free)
{//It will mount just one partition of prt_num>=0.
//When repartitioing whole drive, whole_drive=TRUE.
Expand Down Expand Up @@ -68,6 +79,7 @@ I64 BlkDevAdd(CBlkDev *bd, I64 prt_num=I64_MIN, Bool whole_drive, Bool make_free
break;

case BDT_ATA:
case BDT_USB:
drive->drive_signature = DRIVE_SIGNATURE_VAL; //Temporarily validate
if (!BlkDevInit(bd))
drive->drive_signature = 0; //Revoke validation
Expand All @@ -83,14 +95,14 @@ I64 BlkDevAdd(CBlkDev *bd, I64 prt_num=I64_MIN, Bool whole_drive, Bool make_free
drive->size = bd->max_blk + 1 - bd->drv_offset;
//The following read is a test read.
//if it hangs, the drive is not supported.
AHCIAtaBlksRead(bd, &mbr, 0, 1);
BlkDevAddBlksRead(bd, &mbr, 0, 1);
break;
}
offset = 0;
ext_base = INVALID_CLUS;
while (prt_num < 0 || num <= prt_num)
{
AHCIAtaBlksRead(bd, &mbr, offset, 1);
BlkDevAddBlksRead(bd, &mbr, offset, 1);
if (mbr.signature != 0xAA55)
break;
j = -1;
Expand Down Expand Up @@ -121,7 +133,7 @@ I64 BlkDevAdd(CBlkDev *bd, I64 prt_num=I64_MIN, Bool whole_drive, Bool make_free
case MBR_PT_FAT32d:
case MBR_PT_FAT32e:
case MBR_PT_FAT32f:
AHCIAtaBlksRead(bd, &br, drive->drv_offset, 1);
BlkDevAddBlksRead(bd, &br, drive->drv_offset, 1);

drive->drive_signature = DRIVE_SIGNATURE_VAL;
drive->prt_num = num;
Expand Down
14 changes: 14 additions & 0 deletions src/Kernel/BlkDev/DiskBlk.ZC
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ Bool BlkRead(CDrive *drive, U8 *buf, I64 blk, I64 count)
case BDT_ATAPI:
res = AHCIAtapiRBlks(drive, buf, blk, count);
break;

case BDT_USB:
if (fp_usb_msd_blks_read)
res = (*fp_usb_msd_blks_read)(bd, buf, blk, count);
else
res = FALSE;
break;
}
bd->last_time = tS;
if (bd->flags & BDF_READ_CACHE)
Expand Down Expand Up @@ -117,6 +124,13 @@ Bool BlkWrite(CDrive *drive, U8 *buf, I64 blk, I64 count)
case BDT_ATAPI:
res = AHCIAtaWBlks(drive, buf, blk, count);
break;

case BDT_USB:
if (fp_usb_msd_blks_write)
res = (*fp_usb_msd_blks_write)(bd, buf, blk, count);
else
res = FALSE;
break;
}
bd->last_time = tS;
if (bd->flags & BDF_READ_CACHE)
Expand Down
7 changes: 7 additions & 0 deletions src/Kernel/BlkDev/DiskBlkDev.ZC
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ Bool BlkDevInit(CBlkDev *bd)
if (res = AHCIAtaInit(bd))
drive->size = bd->max_blk + 1;
break;

case BDT_USB:
//USB mass storage driver fills in max_blk before BlkDevAdd().
bd->max_reads = 64;
bd->max_writes = 64;
res = TRUE;
break;
}
if (res && bd->flags & BDF_READ_CACHE)
DiskCacheInvalidate(drive);
Expand Down
6 changes: 4 additions & 2 deletions src/Kernel/BlkDev/DiskDrive.ZC
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,10 @@ I64 Letter2BlkDevType(U8 drv_let)
return BDT_ISO_FILE_READ;
if ('Q' <= drv_let <= 'S')
return BDT_ISO_FILE_WRITE;
if ('T' <= drv_let <= 'Z')
if ('T' <= drv_let <= 'U')
return BDT_ATAPI;
if ('V' <= drv_let <= 'Z')
return BDT_USB;

return BDT_NULL;
}
Expand Down Expand Up @@ -347,7 +349,7 @@ U8 *DriveModelNum(U8 drv_let=0)
return res;
}

U8 blkdev_text_attr[BDT_TYPES_NUM] = {BLACK, LTCYAN, WHITE, LTGREEN, LTRED, LTBLUE};
U8 blkdev_text_attr[BDT_TYPES_NUM] = {BLACK, LTCYAN, WHITE, LTGREEN, LTRED, LTBLUE, LTPURPLE};
U8 drv_text_attr[3] = {BLACK, BLUE, RED};

U8 DriveTextAttrGet(U8 drv_let=0)
Expand Down
3 changes: 2 additions & 1 deletion src/Kernel/KDefine.ZC
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ U0 SysDefinesLoad()
"ATA\0"
"FILE_READ\0"
"FILE_WRITE\0"
"ATAPI\0");
"ATAPI\0"
"USB\0");

DefineListLoad("ST_DRIVE_TYPES",
"NULL\0"
Expand Down
3 changes: 3 additions & 0 deletions src/Kernel/KGlobals.ZC
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ CMouseHardStateGlobals mouse_hard, mouse_hard_last;
CScreenCastGlobals screencast;
CTextGlobals text;

Bool (*fp_usb_msd_blks_read )(CBlkDev *bd, U8 *buf, I64 blk, I64 count); //Set by USB mass storage driver.
Bool (*fp_usb_msd_blks_write)(CBlkDev *bd, U8 *buf, I64 blk, I64 count);

U8 *(*fp_getstr2)(I64 flags=0);
U0 (*fp_update_ctrls)(CTask *task);
CDoc *(*fp_doc_put)(CTask *task=NULL);
Expand Down
3 changes: 2 additions & 1 deletion src/Kernel/KernelA.HH
Original file line number Diff line number Diff line change
Expand Up @@ -3319,7 +3319,8 @@ public class CDirEntry
#define BDT_ISO_FILE_READ 3
#define BDT_ISO_FILE_WRITE 4
#define BDT_ATAPI 5
#define BDT_TYPES_NUM 6
#define BDT_USB 6
#define BDT_TYPES_NUM 7

#define BDf_REMOVABLE 0
#define BDf_INITIALIZED 1
Expand Down
2 changes: 2 additions & 0 deletions src/Kernel/KernelC.HH
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ public extern CBlkDev *BlkDevCheck(CBlkDev *bd, Bool except=TRUE);
public extern U0 BlkDevDel( CBlkDev *bd);
public extern Bool BlkDevLock( CBlkDev *bd);
public extern CBlkDev *BlkDevNextFreeSlot(U8 first_drive_let, I64 type);
public extern Bool (*fp_usb_msd_blks_read )(CBlkDev *bd, U8 *buf, I64 blk, I64 count);
public extern Bool (*fp_usb_msd_blks_write)(CBlkDev *bd, U8 *buf, I64 blk, I64 count);
public extern Bool BlkDevUnlock(CBlkDev *bd, Bool reset=FALSE);
public extern U0 BlkDevsRelease();
public extern U0 BlkDevRep();
Expand Down
1 change: 1 addition & 0 deletions src/System/MakeSystem.ZC
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ LBts(&sys_run_level, RLf_DOC);
#include "Define"
#include "WallPaper"
#include "Mouse"
#include "Usb/MakeUsb"
Cd("..");;
155 changes: 155 additions & 0 deletions src/System/Usb/MakeUsb.ZC
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
//USB stack build + boot task.
Cd(__DIR__);;
#include "UsbDefs"
#include "Xhci"
#include "Usb"
#include "UsbHid"
#include "UsbMsd"
Cd("..");;

U0 UsbDrvBind(CUsbDev *dev)
{//Attach class drivers to a freshly configured device.
CUsbIf *uif;
I64 i;

for (i = 0; i < dev->if_count; i++)
{
uif = &dev->ifs[i];
if (!uif->valid)
goto next_if;
if (uif->if_class == USB_CLASS_HID)
{
if (uif->if_subclass == USB_HID_SUBCLASS_BOOT &&
(uif->if_proto == USB_HID_PROTO_KBD || uif->if_proto == USB_HID_PROTO_MOUSE))
UsbHidAttach(dev, uif);
else
SysLog("USB: port %d: non-boot HID interface ignored.\n", dev->port);
}
else if (uif->if_class == USB_CLASS_MSD)
{
if (uif->if_subclass == USB_MSD_SUBCLASS_SCSI)
UsbMsdAttach(dev, uif);
else
SysLog("USB: port %d: MSD subclass 0x%02X unsupported.\n",
dev->port, uif->if_subclass);
}
else if (uif->if_class == USB_CLASS_HUB)
SysLog("USB: port %d: hubs not yet supported.\n", dev->port);
next_if:;
}
}

U0 UsbDrvUnbind(CUsbDev *dev)
{
UsbHidDetach(dev);
UsbMsdDetach(dev);
}

U0 UsbPortScan()
{//Check all root ports for connects/disconnects. USB task only.
CUsbDev *dev, *ndev;
I64 port, sc;

for (port = 0; port < usb_xhci.max_ports; port++)
{
sc = XhciPortSC(port);
if (sc & XHCI_PORTSC_CHANGE_BITS)
XhciPortSCWrite(port, XHCI_PORTSC_PP | (sc & XHCI_PORTSC_CHANGE_BITS));
dev = UsbDevByPort(port);
if (sc & XHCI_PORTSC_CCS)
{
if (!dev)
{
if (XhciPortReset(port))
{
ndev = UsbDevEnum(port);
if (ndev)
UsbDrvBind(ndev);
}
}
}
else if (dev)
{
UsbDrvUnbind(dev);
UsbDevDetachCore(dev);
SysLog("USB: port %d: device removed.\n", port);
}
}
}

public U0 UsbRep()
{//Report attached USB devices.
CUsbDev *dev;
CUsbIf *uif;
I64 i, j;

if (!usb_xhci.present)
{
"No xHCI controller.\n";
return;
}
"xHCI: %d ports, %d slots.\n", usb_xhci.max_ports, usb_xhci.max_slots;
for (i = 0; i < USB_DEVS_MAX; i++)
{
dev = &usb_devs[i];
if (dev->present)
{
"Port %2d: %04X:%04X \"%s\"", dev->port, dev->vendor_id,
dev->product_id, dev->desc_name;
for (j = 0; j < dev->if_count; j++)
{
uif = &dev->ifs[j];
if (uif->if_class == USB_CLASS_HID && uif->if_proto == USB_HID_PROTO_KBD)
" [keyboard]";
else if (uif->if_class == USB_CLASS_HID && uif->if_proto == USB_HID_PROTO_MOUSE)
" [mouse]";
else if (uif->if_class == USB_CLASS_MSD)
" [storage]";
else if (uif->if_class == USB_CLASS_HUB)
" [hub]";
else
" [class %d]", uif->if_class;
}
"\n";
}
}
for (i = 0; i < USB_MSDS_MAX; i++)
if (usb_msds[i].valid && usb_msds[i].ready && usb_msds[i].bd)
"Storage %d: %d MB, drives from %C:.\n", i,
((usb_msds[i].max_lba + 1) * BLK_SIZE) / 0x100000,
usb_msds[i].first_drive_let;
}

U0 UsbTaskMain(I64 dummy=0)
{
I64 tick = 0;

no_warn dummy;
if (!XhciInit)
return;
Sleep(100); //let port connect status settle after reset
UsbPortScan;
while (TRUE)
{
XhciEventPoll;
UsbHidTick;
tick++;
if (usb_xhci.port_change || tick & 0x7F == 0)
{
usb_xhci.port_change = FALSE;
UsbPortScan;
}
Sleep(2);
}
}

U0 UsbInit()
{
MemSet(&usb_xhci, 0, sizeof(CXhciGlobals));
MemSet(usb_devs, 0, sizeof(CUsbDev) * USB_DEVS_MAX);
MemSet(usb_hids, 0, sizeof(CUsbHid) * USB_HIDS_MAX);
MemSet(usb_msds, 0, sizeof(CUsbMsd) * USB_MSDS_MAX);
usb_task = Spawn(&UsbTaskMain, NULL, "USB");
}

UsbInit;
Loading
Loading