Add driver for the PAPR VSCSI virtual SCSI controller. This lets FreeBSD

install directly into standard POWER LPARs, as found for example in
QEMU. The core of this device is the SCSI RDMA protocol as also found in
Infiniband. The SRP portions of the driver will be factored out and placed
/sys/cam in the future to allow them to be used for IB storage. Thanks to
Scott Long for a great deal of implementation help.

Reviewed by:	scottl
Approved by:	re (kib)
This commit is contained in:
Nathan Whitehorn 2013-09-28 15:46:03 +00:00
parent bdad3190a2
commit 391dff8624
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=255927
3 changed files with 1035 additions and 1 deletions

View file

@ -228,6 +228,7 @@ powerpc/ps3/ps3-hvcall.S optional ps3 sc
powerpc/pseries/phyp-hvcall.S optional pseries powerpc64
powerpc/pseries/mmu_phyp.c optional pseries powerpc64
powerpc/pseries/phyp_console.c optional pseries powerpc64
powerpc/pseries/phyp_vscsi.c optional pseries powerpc64 scbus
powerpc/pseries/platform_chrp.c optional pseries
powerpc/pseries/plpar_iommu.c optional pseries powerpc64
powerpc/pseries/rtas_dev.c optional pseries

File diff suppressed because it is too large Load diff

View file

@ -41,12 +41,17 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <powerpc/pseries/plpar_iommu.h>
#include "iommu_if.h"
static int vdevice_probe(device_t);
static int vdevice_attach(device_t);
static const struct ofw_bus_devinfo *vdevice_get_devinfo(device_t dev,
device_t child);
static int vdevice_print_child(device_t dev, device_t child);
static struct resource_list *vdevice_get_resource_list (device_t, device_t);
static struct resource_list *vdevice_get_resource_list(device_t, device_t);
static bus_dma_tag_t vdevice_get_dma_tag(device_t dev, device_t child);
/*
* VDevice devinfo
@ -54,6 +59,7 @@ static struct resource_list *vdevice_get_resource_list (device_t, device_t);
struct vdevice_devinfo {
struct ofw_bus_devinfo mdi_obdinfo;
struct resource_list mdi_resources;
bus_dma_tag_t mdi_dma_tag;
};
static device_method_t vdevice_methods[] = {
@ -81,6 +87,11 @@ static device_method_t vdevice_methods[] = {
DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
/* IOMMU interface */
DEVMETHOD(bus_get_dma_tag, vdevice_get_dma_tag),
DEVMETHOD(iommu_map, phyp_iommu_map),
DEVMETHOD(iommu_unmap, phyp_iommu_unmap),
DEVMETHOD_END
};
@ -200,3 +211,22 @@ vdevice_get_resource_list (device_t dev, device_t child)
return (&dinfo->mdi_resources);
}
static bus_dma_tag_t
vdevice_get_dma_tag(device_t dev, device_t child)
{
struct vdevice_devinfo *dinfo;
while (child != NULL && device_get_parent(child) != dev)
child = device_get_parent(child);
dinfo = device_get_ivars(child);
if (dinfo->mdi_dma_tag == NULL) {
bus_dma_tag_create(bus_get_dma_tag(dev),
1, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
NULL, NULL, BUS_SPACE_MAXSIZE, BUS_SPACE_UNRESTRICTED,
BUS_SPACE_MAXSIZE, 0, NULL, NULL, &dinfo->mdi_dma_tag);
phyp_iommu_set_dma_tag(dev, child, dinfo->mdi_dma_tag);
}
return (dinfo->mdi_dma_tag);
}