Skip to content

Commit 363b4da

Browse files
xiaoguangwulijinxia
authored andcommitted
DM USB: xHCI: refine xHCI PORTSC Register related functions
PORTSC (Port Status and Control Register) register play a very important role in USB sub-system. This patch is used to refine related manipulation functions. Signed-off-by: Xiaoguang Wu <xiaoguang.wu@intel.com> Reviewed-by: Liang Yang <liang3.yang@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com>
1 parent b746377 commit 363b4da

File tree

1 file changed

+30
-38
lines changed

1 file changed

+30
-38
lines changed

devicemodel/hw/pci/xhci.c

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -440,10 +440,13 @@ static void pci_xhci_update_ep_ring(struct pci_xhci_vdev *xdev,
440440
uint32_t streamid, uint64_t ringaddr,
441441
int ccs);
442442
static void pci_xhci_init_port(struct pci_xhci_vdev *xdev, int portn);
443+
static int pci_xhci_connect_port(struct pci_xhci_vdev *xdev, int port,
444+
int usb_speed, int need_intr);
445+
static int pci_xhci_disconnect_port(struct pci_xhci_vdev *xdev, int port,
446+
int need_intr);
443447
static struct pci_xhci_dev_emu *pci_xhci_dev_create(struct pci_xhci_vdev *
444448
xdev, void *dev_data);
445449
static void pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de);
446-
static int pci_xhci_port_chg(struct pci_xhci_vdev *xdev, int port, int conn);
447450
static void pci_xhci_set_evtrb(struct xhci_trb *evtrb, uint64_t port,
448451
uint32_t errcode, uint32_t evtype);
449452
static int pci_xhci_xfer_complete(struct pci_xhci_vdev *xdev,
@@ -472,6 +475,7 @@ pci_xhci_native_usb_dev_conn_cb(void *hci_data, void *dev_data)
472475
void *ud;
473476
uint8_t native_bus, native_pid, native_port;
474477
uint16_t native_vid;
478+
int native_speed;
475479

476480
xdev = hci_data;
477481

@@ -498,6 +502,7 @@ pci_xhci_native_usb_dev_conn_cb(void *hci_data, void *dev_data)
498502
ue->ue_info(ud, USB_INFO_PORT, &native_port, sizeof(native_port));
499503
ue->ue_info(ud, USB_INFO_VID, &native_vid, sizeof(native_vid));
500504
ue->ue_info(ud, USB_INFO_PID, &native_pid, sizeof(native_pid));
505+
ue->ue_info(ud, USB_INFO_SPEED, &native_speed, sizeof(native_speed));
501506
UPRINTF(LDBG, "%04x:%04x %d-%d connecting.\r\n",
502507
native_vid, native_pid, native_bus, native_port);
503508

@@ -543,14 +548,12 @@ pci_xhci_native_usb_dev_conn_cb(void *hci_data, void *dev_data)
543548
xdev->ndevices++;
544549

545550
pci_xhci_reset_slot(xdev, slot);
546-
pci_xhci_init_port(xdev, port);
547-
548551
UPRINTF(LDBG, "%X:%X %d-%d locates in slot %d port %d.\r\n",
549552
native_vid, native_pid, native_bus, native_port,
550553
slot, port);
551554

552555
/* Trigger port change event for the arriving device */
553-
if (pci_xhci_port_chg(xdev, port, 1))
556+
if (pci_xhci_connect_port(xdev, port, native_speed, 1))
554557
UPRINTF(LFTL, "fail to report port event\n");
555558

556559
return 0;
@@ -595,7 +598,7 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
595598
}
596599

597600
UPRINTF(LDBG, "report virtual port %d status\r\n", port);
598-
if (pci_xhci_port_chg(xdev, port, 0)) {
601+
if (pci_xhci_disconnect_port(xdev, port, 1)) {
599602
UPRINTF(LFTL, "fail to report event\r\n");
600603
return -1;
601604
}
@@ -784,32 +787,29 @@ pci_xhci_convert_speed(int lspeed)
784787
}
785788

786789
static int
787-
pci_xhci_port_chg(struct pci_xhci_vdev *xdev, int port, int conn)
790+
pci_xhci_change_port(struct pci_xhci_vdev *xdev, int port, int usb_speed,
791+
int conn, int need_intr)
788792
{
789793
int speed, error;
790794
struct xhci_trb evtrb;
791795
struct pci_xhci_portregs *reg;
792-
struct pci_xhci_dev_emu *dev;
793796

794797
assert(xdev != NULL);
795798

796799
reg = XHCI_PORTREG_PTR(xdev, port);
797-
dev = XHCI_DEVINST_PTR(xdev, port);
798-
if (!dev || !dev->dev_ue || !reg) {
799-
UPRINTF(LWRN, "find nullptr with port %d\r\n", port);
800-
return -1;
801-
}
802-
803800
if (conn == 0) {
804801
reg->portsc &= ~XHCI_PS_CCS;
805802
reg->portsc |= (XHCI_PS_CSC |
806803
XHCI_PS_PLS_SET(UPS_PORT_LS_RX_DET));
807804
} else {
808-
speed = pci_xhci_convert_speed(dev->dev_ue->ue_usbspeed);
805+
speed = pci_xhci_convert_speed(usb_speed);
809806
reg->portsc = XHCI_PS_CCS | XHCI_PS_PP | XHCI_PS_CSC;
810807
reg->portsc |= XHCI_PS_SPEED_SET(speed);
811808
}
812809

810+
if (!need_intr)
811+
return 0;
812+
813813
/* make an event for the guest OS */
814814
pci_xhci_set_evtrb(&evtrb,
815815
port,
@@ -825,6 +825,20 @@ pci_xhci_port_chg(struct pci_xhci_vdev *xdev, int port, int conn)
825825
return (error == XHCI_TRB_ERROR_SUCCESS) ? 0 : -1;
826826
}
827827

828+
static int
829+
pci_xhci_connect_port(struct pci_xhci_vdev *xdev, int port, int usb_speed,
830+
int intr)
831+
{
832+
return pci_xhci_change_port(xdev, port, usb_speed, 1, intr);
833+
}
834+
835+
static int
836+
pci_xhci_disconnect_port(struct pci_xhci_vdev *xdev, int port, int intr)
837+
{
838+
/* for disconnect, the speed is useless */
839+
return pci_xhci_change_port(xdev, port, 0, 0, intr);
840+
}
841+
828842
static void
829843
pci_xhci_set_evtrb(struct xhci_trb *evtrb, uint64_t port, uint32_t errcode,
830844
uint32_t evtype)
@@ -3208,30 +3222,8 @@ pci_xhci_reset_port(struct pci_xhci_vdev *xdev, int portn, int warm)
32083222
static void
32093223
pci_xhci_init_port(struct pci_xhci_vdev *xdev, int portn)
32103224
{
3211-
struct pci_xhci_portregs *port;
3212-
struct pci_xhci_dev_emu *dev;
3213-
3214-
port = XHCI_PORTREG_PTR(xdev, portn);
3215-
dev = XHCI_DEVINST_PTR(xdev, portn);
3216-
if (dev) {
3217-
port->portsc = XHCI_PS_CCS | /* connected */
3218-
XHCI_PS_PP; /* port power */
3219-
3220-
if (dev->dev_ue->ue_usbver == 2) {
3221-
port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_POLL) |
3222-
XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed);
3223-
} else {
3224-
port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_U0) |
3225-
XHCI_PS_PED | /* enabled */
3226-
XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed);
3227-
}
3228-
3229-
UPRINTF(LDBG, "Init port %d 0x%x\n", portn, port->portsc);
3230-
} else {
3231-
port->portsc = XHCI_PS_PLS_SET(UPS_PORT_LS_RX_DET) | XHCI_PS_PP;
3232-
UPRINTF(LDBG, "Init empty port %d 0x%x\n",
3233-
portn, port->portsc);
3234-
}
3225+
XHCI_PORTREG_PTR(xdev, portn)->portsc =
3226+
XHCI_PS_PLS_SET(UPS_PORT_LS_RX_DET) | XHCI_PS_PP;
32353227
}
32363228

32373229
static int

0 commit comments

Comments
 (0)