ia64/xen-unstable
changeset 17952:97b4c5c511f0
minios: PIRQ and MSI/MSI-X support
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Jul 02 17:26:42 2008 +0100 (2008-07-02) |
parents | f2148e532c81 |
children | 3d5f28d6e777 |
files | extras/mini-os/events.c extras/mini-os/include/events.h extras/mini-os/include/pcifront.h extras/mini-os/pcifront.c |
line diff
1.1 --- a/extras/mini-os/events.c Wed Jul 02 17:25:05 2008 +0100 1.2 +++ b/extras/mini-os/events.c Wed Jul 02 17:26:42 2008 +0100 1.3 @@ -136,6 +136,23 @@ evtchn_port_t bind_virq(uint32_t virq, e 1.4 return op.port; 1.5 } 1.6 1.7 +evtchn_port_t bind_pirq(uint32_t pirq, int will_share, evtchn_handler_t handler, void *data) 1.8 +{ 1.9 + evtchn_bind_pirq_t op; 1.10 + 1.11 + /* Try to bind the pirq to a port */ 1.12 + op.pirq = pirq; 1.13 + op.flags = will_share ? BIND_PIRQ__WILL_SHARE : 0; 1.14 + 1.15 + if ( HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &op) != 0 ) 1.16 + { 1.17 + printk("Failed to bind physical IRQ %d\n", pirq); 1.18 + return -1; 1.19 + } 1.20 + bind_evtchn(op.port, handler, data); 1.21 + return op.port; 1.22 +} 1.23 + 1.24 #if defined(__x86_64__) 1.25 char irqstack[2 * STACK_SIZE]; 1.26
2.1 --- a/extras/mini-os/include/events.h Wed Jul 02 17:25:05 2008 +0100 2.2 +++ b/extras/mini-os/include/events.h Wed Jul 02 17:26:42 2008 +0100 2.3 @@ -27,6 +27,7 @@ typedef void (*evtchn_handler_t)(evtchn_ 2.4 /* prototypes */ 2.5 int do_event(evtchn_port_t port, struct pt_regs *regs); 2.6 evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data); 2.7 +evtchn_port_t bind_pirq(uint32_t pirq, int will_share, evtchn_handler_t handler, void *data); 2.8 evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler, 2.9 void *data); 2.10 void unbind_evtchn(evtchn_port_t port);
3.1 --- a/extras/mini-os/include/pcifront.h Wed Jul 02 17:25:05 2008 +0100 3.2 +++ b/extras/mini-os/include/pcifront.h Wed Jul 02 17:26:42 2008 +0100 3.3 @@ -2,9 +2,8 @@ 3.4 #include <xen/io/pciif.h> 3.5 struct pcifront_dev; 3.6 struct pcifront_dev *init_pcifront(char *nodename); 3.7 +void pcifront_op(struct pcifront_dev *dev, struct xen_pci_op *op); 3.8 void pcifront_scan(struct pcifront_dev *dev, void (*fun)(unsigned int domain, unsigned int bus, unsigned slot, unsigned int fun)); 3.9 -void pcifront_op(struct pcifront_dev *dev, struct xen_pci_op *op); 3.10 -void shutdown_pcifront(struct pcifront_dev *dev); 3.11 int pcifront_conf_read(struct pcifront_dev *dev, 3.12 unsigned int dom, 3.13 unsigned int bus, unsigned int slot, unsigned long fun, 3.14 @@ -13,3 +12,17 @@ int pcifront_conf_write(struct pcifront_ 3.15 unsigned int dom, 3.16 unsigned int bus, unsigned int slot, unsigned long fun, 3.17 unsigned int off, unsigned int size, unsigned int val); 3.18 +int pcifront_enable_msi(struct pcifront_dev *dev, 3.19 + unsigned int dom, 3.20 + unsigned int bus, unsigned int slot, unsigned long fun); 3.21 +int pcifront_disable_msi(struct pcifront_dev *dev, 3.22 + unsigned int dom, 3.23 + unsigned int bus, unsigned int slot, unsigned long fun); 3.24 +int pcifront_enable_msix(struct pcifront_dev *dev, 3.25 + unsigned int dom, 3.26 + unsigned int bus, unsigned int slot, unsigned long fun, 3.27 + struct xen_msix_entry *entries, int n); 3.28 +int pcifront_disable_msix(struct pcifront_dev *dev, 3.29 + unsigned int dom, 3.30 + unsigned int bus, unsigned int slot, unsigned long fun); 3.31 +void shutdown_pcifront(struct pcifront_dev *dev);
4.1 --- a/extras/mini-os/pcifront.c Wed Jul 02 17:25:05 2008 +0100 4.2 +++ b/extras/mini-os/pcifront.c Wed Jul 02 17:26:42 2008 +0100 4.3 @@ -276,3 +276,91 @@ int pcifront_conf_write(struct pcifront_ 4.4 4.5 return op.err; 4.6 } 4.7 + 4.8 +int pcifront_enable_msi(struct pcifront_dev *dev, 4.9 + unsigned int dom, 4.10 + unsigned int bus, unsigned int slot, unsigned long fun) 4.11 +{ 4.12 + struct xen_pci_op op; 4.13 + 4.14 + memset(&op, 0, sizeof(op)); 4.15 + 4.16 + op.cmd = XEN_PCI_OP_enable_msi; 4.17 + op.domain = dom; 4.18 + op.bus = bus; 4.19 + op.devfn = PCI_DEVFN(slot, fun); 4.20 + 4.21 + pcifront_op(dev, &op); 4.22 + 4.23 + if (op.err) 4.24 + return op.err; 4.25 + else 4.26 + return op.value; 4.27 +} 4.28 + 4.29 +int pcifront_disable_msi(struct pcifront_dev *dev, 4.30 + unsigned int dom, 4.31 + unsigned int bus, unsigned int slot, unsigned long fun) 4.32 +{ 4.33 + struct xen_pci_op op; 4.34 + 4.35 + memset(&op, 0, sizeof(op)); 4.36 + 4.37 + op.cmd = XEN_PCI_OP_disable_msi; 4.38 + op.domain = dom; 4.39 + op.bus = bus; 4.40 + op.devfn = PCI_DEVFN(slot, fun); 4.41 + 4.42 + pcifront_op(dev, &op); 4.43 + 4.44 + return op.err; 4.45 +} 4.46 + 4.47 +int pcifront_enable_msix(struct pcifront_dev *dev, 4.48 + unsigned int dom, 4.49 + unsigned int bus, unsigned int slot, unsigned long fun, 4.50 + struct xen_msix_entry *entries, int n) 4.51 +{ 4.52 + struct xen_pci_op op; 4.53 + 4.54 + if (n > SH_INFO_MAX_VEC) 4.55 + return XEN_PCI_ERR_op_failed; 4.56 + 4.57 + memset(&op, 0, sizeof(op)); 4.58 + 4.59 + op.cmd = XEN_PCI_OP_enable_msix; 4.60 + op.domain = dom; 4.61 + op.bus = bus; 4.62 + op.devfn = PCI_DEVFN(slot, fun); 4.63 + op.value = n; 4.64 + 4.65 + memcpy(op.msix_entries, entries, n * sizeof(*entries)); 4.66 + 4.67 + pcifront_op(dev, &op); 4.68 + 4.69 + if (op.err) 4.70 + return op.err; 4.71 + 4.72 + memcpy(entries, op.msix_entries, n * sizeof(*entries)); 4.73 + 4.74 + return 0; 4.75 +} 4.76 + 4.77 + 4.78 +int pcifront_disable_msix(struct pcifront_dev *dev, 4.79 + unsigned int dom, 4.80 + unsigned int bus, unsigned int slot, unsigned long fun) 4.81 +{ 4.82 + struct xen_pci_op op; 4.83 + 4.84 + memset(&op, 0, sizeof(op)); 4.85 + 4.86 + op.cmd = XEN_PCI_OP_disable_msix; 4.87 + op.domain = dom; 4.88 + op.bus = bus; 4.89 + op.devfn = PCI_DEVFN(slot, fun); 4.90 + 4.91 + pcifront_op(dev, &op); 4.92 + 4.93 + return op.err; 4.94 +}