This patch adds the feature to provide PCI information via IOCTL query.
Reviewed by: ambrisko MFC after: 2 weeks Sponsored by: AVAGO Technologies
This commit is contained in:
parent
6b7074e362
commit
89cb6b04b0
@ -87,6 +87,8 @@ mrsas_get_ctrl_info(struct mrsas_softc *sc,
|
||||
static int
|
||||
mrsas_issue_blocked_abort_cmd(struct mrsas_softc *sc,
|
||||
struct mrsas_mfi_cmd *cmd_to_abort);
|
||||
static struct mrsas_softc *mrsas_get_softc_instance(struct cdev *dev,
|
||||
u_long cmd, caddr_t arg);
|
||||
u_int32_t mrsas_read_reg(struct mrsas_softc *sc, int offset);
|
||||
u_int8_t
|
||||
mrsas_build_mptmfi_passthru(struct mrsas_softc *sc,
|
||||
@ -1231,6 +1233,39 @@ mrsas_resume(device_t dev)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* mrsas_get_softc_instance: Find softc instance based on cmd type
|
||||
*
|
||||
* This function will return softc instance based on cmd type.
|
||||
* In some case, application fire ioctl on required management instance and
|
||||
* do not provide host_no. Use cdev->si_drv1 to get softc instance for those
|
||||
* case, else get the softc instance from host_no provided by application in
|
||||
* user data.
|
||||
*/
|
||||
|
||||
static struct mrsas_softc *
|
||||
mrsas_get_softc_instance(struct cdev *dev, u_long cmd, caddr_t arg)
|
||||
{
|
||||
struct mrsas_softc *sc = NULL;
|
||||
struct mrsas_iocpacket *user_ioc = (struct mrsas_iocpacket *)arg;
|
||||
if (cmd == MRSAS_IOC_GET_PCI_INFO){
|
||||
sc = dev->si_drv1;
|
||||
} else {
|
||||
/* get the Host number & the softc from data sent by the Application */
|
||||
sc = mrsas_mgmt_info.sc_ptr[user_ioc->host_no];
|
||||
if ((user_ioc->host_no >= mrsas_mgmt_info.max_index) || (sc == NULL)) {
|
||||
if (sc == NULL)
|
||||
mrsas_dprint(sc, MRSAS_FAULT,
|
||||
"There is no Controller number %d .\n", user_ioc->host_no);
|
||||
else
|
||||
mrsas_dprint(sc, MRSAS_FAULT,
|
||||
"Invalid Controller number %d .\n", user_ioc->host_no);
|
||||
}
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
/*
|
||||
* mrsas_ioctl: IOCtl commands entry point.
|
||||
*
|
||||
@ -1243,19 +1278,12 @@ mrsas_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag,
|
||||
{
|
||||
struct mrsas_softc *sc;
|
||||
int ret = 0, i = 0;
|
||||
MRSAS_DRV_PCI_INFORMATION *pciDrvInfo;
|
||||
|
||||
struct mrsas_iocpacket *user_ioc = (struct mrsas_iocpacket *)arg;
|
||||
|
||||
/* get the Host number & the softc from data sent by the Application */
|
||||
sc = mrsas_mgmt_info.sc_ptr[user_ioc->host_no];
|
||||
|
||||
if ((mrsas_mgmt_info.max_index == user_ioc->host_no) || (sc == NULL)) {
|
||||
printf("Please check the controller number\n");
|
||||
if (sc == NULL)
|
||||
printf("There is NO such Host no. %d\n", user_ioc->host_no);
|
||||
|
||||
sc = mrsas_get_softc_instance(dev, cmd, arg);
|
||||
if (!sc)
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (sc->remove_in_progress) {
|
||||
mrsas_dprint(sc, MRSAS_INFO,
|
||||
"Driver remove or shutdown called.\n");
|
||||
@ -1299,6 +1327,22 @@ mrsas_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag,
|
||||
case MRSAS_IOC_SCAN_BUS:
|
||||
ret = mrsas_bus_scan(sc);
|
||||
break;
|
||||
|
||||
case MRSAS_IOC_GET_PCI_INFO:
|
||||
pciDrvInfo = (MRSAS_DRV_PCI_INFORMATION *)arg;
|
||||
memset (pciDrvInfo, 0, sizeof(MRSAS_DRV_PCI_INFORMATION));
|
||||
pciDrvInfo->busNumber = pci_get_bus(sc->mrsas_dev);
|
||||
pciDrvInfo->deviceNumber = pci_get_slot(sc->mrsas_dev);
|
||||
pciDrvInfo->functionNumber = pci_get_function(sc->mrsas_dev);
|
||||
pciDrvInfo->domainID = pci_get_domain(sc->mrsas_dev);
|
||||
mrsas_dprint (sc, MRSAS_INFO, "pci bus no: %d,"
|
||||
"pci device no: %d, pci function no: %d,"
|
||||
"pci domain ID: %d\n",
|
||||
pciDrvInfo->busNumber, pciDrvInfo->deviceNumber,
|
||||
pciDrvInfo->functionNumber, pciDrvInfo->domainID);
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
mrsas_dprint(sc, MRSAS_TRACE, "IOCTL command 0x%lx is not handled\n", cmd);
|
||||
ret = ENOENT;
|
||||
|
@ -2413,6 +2413,167 @@ struct mrsas_mgmt_info {
|
||||
int max_index;
|
||||
};
|
||||
|
||||
#define PCI_TYPE0_ADDRESSES 6
|
||||
#define PCI_TYPE1_ADDRESSES 2
|
||||
#define PCI_TYPE2_ADDRESSES 5
|
||||
|
||||
typedef struct _MRSAS_DRV_PCI_COMMON_HEADER
|
||||
{
|
||||
u_int16_t vendorID; // (ro)
|
||||
u_int16_t deviceID; // (ro)
|
||||
u_int16_t command; // Device control
|
||||
u_int16_t status;
|
||||
u_int8_t revisionID; // (ro)
|
||||
u_int8_t progIf; // (ro)
|
||||
u_int8_t subClass; // (ro)
|
||||
u_int8_t baseClass; // (ro)
|
||||
u_int8_t cacheLineSize; // (ro+)
|
||||
u_int8_t latencyTimer; // (ro+)
|
||||
u_int8_t headerType; // (ro)
|
||||
u_int8_t bist; // Built in self test
|
||||
|
||||
union
|
||||
{
|
||||
struct _MRSAS_DRV_PCI_HEADER_TYPE_0
|
||||
{
|
||||
u_int32_t baseAddresses[PCI_TYPE0_ADDRESSES];
|
||||
u_int32_t cis;
|
||||
u_int16_t subVendorID;
|
||||
u_int16_t subSystemID;
|
||||
u_int32_t romBaseAddress;
|
||||
u_int8_t capabilitiesPtr;
|
||||
u_int8_t reserved1[3];
|
||||
u_int32_t reserved2;
|
||||
u_int8_t interruptLine;
|
||||
u_int8_t interruptPin; // (ro)
|
||||
u_int8_t minimumGrant; // (ro)
|
||||
u_int8_t maximumLatency; // (ro)
|
||||
} type0;
|
||||
|
||||
/*
|
||||
* PCI to PCI Bridge
|
||||
*/
|
||||
|
||||
struct _MRSAS_DRV_PCI_HEADER_TYPE_1
|
||||
{
|
||||
u_int32_t baseAddresses[PCI_TYPE1_ADDRESSES];
|
||||
u_int8_t primaryBus;
|
||||
u_int8_t secondaryBus;
|
||||
u_int8_t subordinateBus;
|
||||
u_int8_t secondaryLatency;
|
||||
u_int8_t ioBase;
|
||||
u_int8_t ioLimit;
|
||||
u_int16_t secondaryStatus;
|
||||
u_int16_t memoryBase;
|
||||
u_int16_t memoryLimit;
|
||||
u_int16_t prefetchBase;
|
||||
u_int16_t prefetchLimit;
|
||||
u_int32_t prefetchBaseUpper32;
|
||||
u_int32_t prefetchLimitUpper32;
|
||||
u_int16_t ioBaseUpper16;
|
||||
u_int16_t ioLimitUpper16;
|
||||
u_int8_t capabilitiesPtr;
|
||||
u_int8_t reserved1[3];
|
||||
u_int32_t romBaseAddress;
|
||||
u_int8_t interruptLine;
|
||||
u_int8_t interruptPin;
|
||||
u_int16_t bridgeControl;
|
||||
} type1;
|
||||
|
||||
/*
|
||||
* PCI to CARDBUS Bridge
|
||||
*/
|
||||
|
||||
struct _MRSAS_DRV_PCI_HEADER_TYPE_2
|
||||
{
|
||||
u_int32_t socketRegistersBaseAddress;
|
||||
u_int8_t capabilitiesPtr;
|
||||
u_int8_t reserved;
|
||||
u_int16_t secondaryStatus;
|
||||
u_int8_t primaryBus;
|
||||
u_int8_t secondaryBus;
|
||||
u_int8_t subordinateBus;
|
||||
u_int8_t secondaryLatency;
|
||||
struct
|
||||
{
|
||||
u_int32_t base;
|
||||
u_int32_t limit;
|
||||
} range[PCI_TYPE2_ADDRESSES-1];
|
||||
u_int8_t interruptLine;
|
||||
u_int8_t interruptPin;
|
||||
u_int16_t bridgeControl;
|
||||
} type2;
|
||||
} u;
|
||||
|
||||
} MRSAS_DRV_PCI_COMMON_HEADER, *PMRSAS_DRV_PCI_COMMON_HEADER;
|
||||
|
||||
#define MRSAS_DRV_PCI_COMMON_HEADER_SIZE sizeof(MRSAS_DRV_PCI_COMMON_HEADER) //64 bytes
|
||||
|
||||
typedef struct _MRSAS_DRV_PCI_LINK_CAPABILITY
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u_int32_t linkSpeed :4;
|
||||
u_int32_t linkWidth :6;
|
||||
u_int32_t aspmSupport :2;
|
||||
u_int32_t losExitLatency :3;
|
||||
u_int32_t l1ExitLatency :3;
|
||||
u_int32_t rsvdp :6;
|
||||
u_int32_t portNumber :8;
|
||||
}bits;
|
||||
|
||||
u_int32_t asUlong;
|
||||
}u;
|
||||
}MRSAS_DRV_PCI_LINK_CAPABILITY, *PMRSAS_DRV_PCI_LINK_CAPABILITY;
|
||||
|
||||
#define MRSAS_DRV_PCI_LINK_CAPABILITY_SIZE sizeof(MRSAS_DRV_PCI_LINK_CAPABILITY)
|
||||
|
||||
typedef struct _MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u_int16_t linkSpeed :4;
|
||||
u_int16_t negotiatedLinkWidth :6;
|
||||
u_int16_t linkTrainingError :1;
|
||||
u_int16_t linkTraning :1;
|
||||
u_int16_t slotClockConfig :1;
|
||||
u_int16_t rsvdZ :3;
|
||||
}bits;
|
||||
|
||||
u_int16_t asUshort;
|
||||
}u;
|
||||
u_int16_t reserved;
|
||||
} MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY, *PMRSAS_DRV_PCI_LINK_STATUS_CAPABILITY;
|
||||
|
||||
#define MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY_SIZE sizeof(MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY)
|
||||
|
||||
|
||||
typedef struct _MRSAS_DRV_PCI_CAPABILITIES
|
||||
{
|
||||
MRSAS_DRV_PCI_LINK_CAPABILITY linkCapability;
|
||||
MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY linkStatusCapability;
|
||||
}MRSAS_DRV_PCI_CAPABILITIES, *PMRSAS_DRV_PCI_CAPABILITIES;
|
||||
|
||||
#define MRSAS_DRV_PCI_CAPABILITIES_SIZE sizeof(MRSAS_DRV_PCI_CAPABILITIES)
|
||||
|
||||
/* PCI information */
|
||||
typedef struct _MRSAS_DRV_PCI_INFORMATION
|
||||
{
|
||||
u_int32_t busNumber;
|
||||
u_int8_t deviceNumber;
|
||||
u_int8_t functionNumber;
|
||||
u_int8_t interruptVector;
|
||||
u_int8_t reserved1;
|
||||
MRSAS_DRV_PCI_COMMON_HEADER pciHeaderInfo;
|
||||
MRSAS_DRV_PCI_CAPABILITIES capability;
|
||||
u_int32_t domainID;
|
||||
u_int8_t reserved2[28];
|
||||
}MRSAS_DRV_PCI_INFORMATION, *PMRSAS_DRV_PCI_INFORMATION;
|
||||
|
||||
/*******************************************************************
|
||||
* per-instance data
|
||||
********************************************************************/
|
||||
|
@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
|
||||
* into a somewhat unique, 32-bit value.
|
||||
*/
|
||||
|
||||
#define MRSAS_IOC_GET_PCI_INFO _IOR('M', 7, MRSAS_DRV_PCI_INFORMATION)
|
||||
#define MRSAS_IOC_FIRMWARE_PASS_THROUGH64 _IOWR('M', 1, struct mrsas_iocpacket)
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
#define MRSAS_IOC_FIRMWARE_PASS_THROUGH32 _IOWR('M', 1, struct mrsas_iocpacket32)
|
||||
|
Loading…
Reference in New Issue
Block a user