Implemented interrupt Config Hook in mrsas(4) to defer some of the tasks, like:

riegistering AEN, creating cdev.

Submitted by:   Sumit Saxena <sumit.saxena@broadcom.com>
Reviewed by:    Kashyap Desai <Kashyap.Desai@broadcom.com>
MFC after:  3 days
Sponsored by:   AVAGO Technologies
This commit is contained in:
Kashyap D Desai 2016-05-13 12:15:20 +00:00
parent 3a3fc6cba6
commit 8071588d7a
2 changed files with 78 additions and 45 deletions

View File

@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/sysent.h>
#include <sys/kthread.h> #include <sys/kthread.h>
#include <sys/taskqueue.h> #include <sys/taskqueue.h>
#include <sys/smp.h> #include <sys/smp.h>
@ -63,6 +64,7 @@ static d_write_t mrsas_write;
static d_ioctl_t mrsas_ioctl; static d_ioctl_t mrsas_ioctl;
static d_poll_t mrsas_poll; static d_poll_t mrsas_poll;
static void mrsas_ich_startup(void *arg);
static struct mrsas_mgmt_info mrsas_mgmt_info; static struct mrsas_mgmt_info mrsas_mgmt_info;
static struct mrsas_ident *mrsas_find_ident(device_t); static struct mrsas_ident *mrsas_find_ident(device_t);
static int mrsas_setup_msix(struct mrsas_softc *sc); static int mrsas_setup_msix(struct mrsas_softc *sc);
@ -822,7 +824,6 @@ mrsas_attach(device_t dev)
{ {
struct mrsas_softc *sc = device_get_softc(dev); struct mrsas_softc *sc = device_get_softc(dev);
uint32_t cmd, bar, error; uint32_t cmd, bar, error;
struct cdev *linux_dev;
/* Look up our softc and initialize its fields. */ /* Look up our softc and initialize its fields. */
sc->mrsas_dev = dev; sc->mrsas_dev = dev;
@ -863,12 +864,6 @@ mrsas_attach(device_t dev)
mtx_init(&sc->mfi_cmd_pool_lock, "mrsas_mfi_cmd_pool_lock", NULL, MTX_DEF); mtx_init(&sc->mfi_cmd_pool_lock, "mrsas_mfi_cmd_pool_lock", NULL, MTX_DEF);
mtx_init(&sc->raidmap_lock, "mrsas_raidmap_lock", NULL, MTX_DEF); mtx_init(&sc->raidmap_lock, "mrsas_raidmap_lock", NULL, MTX_DEF);
/*
* Intialize a counting Semaphore to take care no. of concurrent
* IOCTLs
*/
sema_init(&sc->ioctl_count_sema, MRSAS_MAX_MFI_CMDS - 5, IOCTL_SEMA_DESCRIPTION);
/* Intialize linked list */ /* Intialize linked list */
TAILQ_INIT(&sc->mrsas_mpt_cmd_list_head); TAILQ_INIT(&sc->mrsas_mpt_cmd_list_head);
TAILQ_INIT(&sc->mrsas_mfi_cmd_list_head); TAILQ_INIT(&sc->mrsas_mfi_cmd_list_head);
@ -877,16 +872,6 @@ mrsas_attach(device_t dev)
sc->io_cmds_highwater = 0; sc->io_cmds_highwater = 0;
/* Create a /dev entry for this device. */
sc->mrsas_cdev = make_dev(&mrsas_cdevsw, device_get_unit(dev), UID_ROOT,
GID_OPERATOR, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP), "mrsas%u",
device_get_unit(dev));
if (device_get_unit(dev) == 0)
make_dev_alias_p(MAKEDEV_CHECKNAME, &linux_dev, sc->mrsas_cdev,
"megaraid_sas_ioctl_node");
if (sc->mrsas_cdev)
sc->mrsas_cdev->si_drv1 = sc;
sc->adprecovery = MRSAS_HBA_OPERATIONAL; sc->adprecovery = MRSAS_HBA_OPERATIONAL;
sc->UnevenSpanSupport = 0; sc->UnevenSpanSupport = 0;
@ -896,7 +881,7 @@ mrsas_attach(device_t dev)
if (mrsas_init_fw(sc) != SUCCESS) { if (mrsas_init_fw(sc) != SUCCESS) {
goto attach_fail_fw; goto attach_fail_fw;
} }
/* Register SCSI mid-layer */ /* Register mrsas to CAM layer */
if ((mrsas_cam_attach(sc) != SUCCESS)) { if ((mrsas_cam_attach(sc) != SUCCESS)) {
goto attach_fail_cam; goto attach_fail_cam;
} }
@ -904,38 +889,28 @@ mrsas_attach(device_t dev)
if (mrsas_setup_irq(sc) != SUCCESS) { if (mrsas_setup_irq(sc) != SUCCESS) {
goto attach_fail_irq; goto attach_fail_irq;
} }
/* Enable Interrupts */
mrsas_enable_intr(sc);
error = mrsas_kproc_create(mrsas_ocr_thread, sc, error = mrsas_kproc_create(mrsas_ocr_thread, sc,
&sc->ocr_thread, 0, 0, "mrsas_ocr%d", &sc->ocr_thread, 0, 0, "mrsas_ocr%d",
device_get_unit(sc->mrsas_dev)); device_get_unit(sc->mrsas_dev));
if (error) { if (error) {
printf("Error %d starting rescan thread\n", error); device_printf(sc->mrsas_dev, "Error %d starting OCR thread\n", error);
goto attach_fail_irq; goto attach_fail_ocr_thread;
}
mrsas_setup_sysctl(sc);
/* Initiate AEN (Asynchronous Event Notification) */
if (mrsas_start_aen(sc)) {
printf("Error: start aen failed\n");
goto fail_start_aen;
} }
/* /*
* Add this controller to mrsas_mgmt_info structure so that it can be * After FW initialization and OCR thread creation
* exported to management applications * we will defer the cdev creation, AEN setup on ICH callback
*/ */
if (device_get_unit(dev) == 0) sc->mrsas_ich.ich_func = mrsas_ich_startup;
memset(&mrsas_mgmt_info, 0, sizeof(mrsas_mgmt_info)); sc->mrsas_ich.ich_arg = sc;
if (config_intrhook_establish(&sc->mrsas_ich) != 0) {
device_printf(sc->mrsas_dev, "Config hook is already established\n");
}
mrsas_setup_sysctl(sc);
return SUCCESS;
mrsas_mgmt_info.count++; attach_fail_ocr_thread:
mrsas_mgmt_info.sc_ptr[mrsas_mgmt_info.max_index] = sc; if (sc->ocr_thread_active)
mrsas_mgmt_info.max_index++; wakeup(&sc->ocr_chan);
return (0);
fail_start_aen:
attach_fail_irq: attach_fail_irq:
mrsas_teardown_intr(sc); mrsas_teardown_intr(sc);
attach_fail_cam: attach_fail_cam:
@ -953,10 +928,7 @@ attach_fail_fw:
mtx_destroy(&sc->mpt_cmd_pool_lock); mtx_destroy(&sc->mpt_cmd_pool_lock);
mtx_destroy(&sc->mfi_cmd_pool_lock); mtx_destroy(&sc->mfi_cmd_pool_lock);
mtx_destroy(&sc->raidmap_lock); mtx_destroy(&sc->raidmap_lock);
/* Destroy the counting semaphore created for Ioctl */
sema_destroy(&sc->ioctl_count_sema);
attach_fail: attach_fail:
destroy_dev(sc->mrsas_cdev);
if (sc->reg_res) { if (sc->reg_res) {
bus_release_resource(sc->mrsas_dev, SYS_RES_MEMORY, bus_release_resource(sc->mrsas_dev, SYS_RES_MEMORY,
sc->reg_res_id, sc->reg_res); sc->reg_res_id, sc->reg_res);
@ -964,6 +936,63 @@ attach_fail:
return (ENXIO); return (ENXIO);
} }
/*
* Interrupt config hook
*/
static void
mrsas_ich_startup(void *arg)
{
struct mrsas_softc *sc = (struct mrsas_softc *)arg;
/*
* Intialize a counting Semaphore to take care no. of concurrent IOCTLs
*/
sema_init(&sc->ioctl_count_sema,
MRSAS_MAX_MFI_CMDS - 5,
IOCTL_SEMA_DESCRIPTION);
/* Create a /dev entry for mrsas controller. */
sc->mrsas_cdev = make_dev(&mrsas_cdevsw, device_get_unit(sc->mrsas_dev), UID_ROOT,
GID_OPERATOR, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP), "mrsas%u",
device_get_unit(sc->mrsas_dev));
if (device_get_unit(sc->mrsas_dev) == 0) {
make_dev_alias_p(MAKEDEV_CHECKNAME,
&sc->mrsas_linux_emulator_cdev, sc->mrsas_cdev,
"megaraid_sas_ioctl_node");
}
if (sc->mrsas_cdev)
sc->mrsas_cdev->si_drv1 = sc;
/*
* Add this controller to mrsas_mgmt_info structure so that it can be
* exported to management applications
*/
if (device_get_unit(sc->mrsas_dev) == 0)
memset(&mrsas_mgmt_info, 0, sizeof(mrsas_mgmt_info));
mrsas_mgmt_info.count++;
mrsas_mgmt_info.sc_ptr[mrsas_mgmt_info.max_index] = sc;
mrsas_mgmt_info.max_index++;
/* Enable Interrupts */
mrsas_enable_intr(sc);
/* Initiate AEN (Asynchronous Event Notification) */
if (mrsas_start_aen(sc)) {
device_printf(sc->mrsas_dev, "Error: AEN registration FAILED !!! "
"Further events from the controller will not be communicated.\n"
"Either there is some problem in the controller"
"or the controller does not support AEN.\n"
"Please contact to the SUPPORT TEAM if the problem persists\n");
}
if (sc->mrsas_ich.ich_arg != NULL) {
device_printf(sc->mrsas_dev, "Disestablish mrsas intr hook\n");
config_intrhook_disestablish(&sc->mrsas_ich);
sc->mrsas_ich.ich_arg = NULL;
}
}
/* /*
* mrsas_detach: De-allocates and teardown resources * mrsas_detach: De-allocates and teardown resources
* input: pointer to device struct * input: pointer to device struct
@ -982,6 +1011,8 @@ mrsas_detach(device_t dev)
sc->remove_in_progress = 1; sc->remove_in_progress = 1;
/* Destroy the character device so no other IOCTL will be handled */ /* Destroy the character device so no other IOCTL will be handled */
if ((device_get_unit(dev) == 0) && sc->mrsas_linux_emulator_cdev)
destroy_dev(sc->mrsas_linux_emulator_cdev);
destroy_dev(sc->mrsas_cdev); destroy_dev(sc->mrsas_cdev);
/* /*

View File

@ -2646,6 +2646,8 @@ typedef struct _MRSAS_DRV_PCI_INFORMATION {
struct mrsas_softc { struct mrsas_softc {
device_t mrsas_dev; device_t mrsas_dev;
struct cdev *mrsas_cdev; struct cdev *mrsas_cdev;
struct intr_config_hook mrsas_ich;
struct cdev *mrsas_linux_emulator_cdev;
uint16_t device_id; uint16_t device_id;
struct resource *reg_res; struct resource *reg_res;
int reg_res_id; int reg_res_id;