The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/smartpqi/smartpqi_helper.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright 2016-2021 Microchip Technology, Inc. and/or its subsidiaries.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   23  * SUCH DAMAGE.
   24  */
   25 
   26 /* $FreeBSD$ */
   27 
   28 #include "smartpqi_includes.h"
   29 
   30 /* read and modify controller diagnostic option - PQI_PTRAID_UPDATE_ON_RESCAN_LUNS */
   31 void
   32 pqisrc_ctrl_diagnostic_options(pqisrc_softstate_t *softs)
   33 {
   34         int ret = PQI_STATUS_SUCCESS;
   35         uint32_t diags_options = 0;
   36         pqisrc_raid_req_t request;
   37 
   38         DBG_NOTE("IN\n");
   39 
   40         memset(&request, 0, sizeof(request));
   41         /* read diags options of controller */
   42         ret =  pqisrc_build_send_raid_request(softs, &request,
   43                                         (void*)&diags_options,
   44                                         sizeof(diags_options),
   45                                         BMIC_SENSE_DIAGS_OPTIONS,
   46                                         0, (uint8_t *)RAID_CTLR_LUNID, NULL);
   47         if (ret != PQI_STATUS_SUCCESS) {
   48                 DBG_WARN("Request failed for BMIC Sense Diags Option command."
   49                         "ret:%d\n",ret);
   50                 return;
   51         }
   52         DBG_NOTE("diags options data after read: %#x\n",diags_options);
   53         diags_options |= PQI_PTRAID_UPDATE_ON_RESCAN_LUNS;
   54         DBG_NOTE("diags options data to write: %#x\n",diags_options);
   55         memset(&request, 0, sizeof(request));
   56         /* write specified diags options to controller */
   57         ret =  pqisrc_build_send_raid_request(softs, &request,
   58                                         (void*)&diags_options,
   59                                         sizeof(diags_options),
   60                                         BMIC_SET_DIAGS_OPTIONS,
   61                                         0, (uint8_t *)RAID_CTLR_LUNID, NULL);
   62         if (ret != PQI_STATUS_SUCCESS)
   63                 DBG_WARN("Request failed for BMIC Set Diags Option command."
   64                         "ret:%d\n",ret);
   65 #if 0
   66         diags_options = 0;
   67         memset(&request, 0, sizeof(request));
   68         ret =  pqisrc_build_send_raid_request(softs, &request,
   69                                         (void*)&diags_options,
   70                                         sizeof(diags_options),
   71                                         BMIC_SENSE_DIAGS_OPTIONS,
   72                                         0, (uint8_t *)RAID_CTLR_LUNID, NULL);
   73         if (ret != PQI_STATUS_SUCCESS)
   74                 DBG_WARN("Request failed for BMIC Sense Diags Option command."
   75                         "ret:%d\n",ret);
   76         DBG_NOTE("diags options after re-read: %#x\n",diags_options);
   77 #endif
   78         DBG_NOTE("OUT\n");
   79 }
   80 
   81 /*
   82  * Function used to validate the adapter health.
   83  */
   84 boolean_t
   85 pqisrc_ctrl_offline(pqisrc_softstate_t *softs)
   86 {
   87         DBG_FUNC("IN\n");
   88 
   89         DBG_FUNC("OUT\n");
   90 
   91         return !softs->ctrl_online;
   92 }
   93 
   94 /* Function used set/clear legacy INTx bit in Legacy Interrupt INTx
   95  * mask clear pqi register
   96  */
   97 void
   98 pqisrc_configure_legacy_intx(pqisrc_softstate_t *softs, boolean_t enable_intx)
   99 {
  100         uint32_t intx_mask;
  101         uint32_t *reg_addr __unused;
  102 
  103         DBG_FUNC("IN\n");
  104 
  105         if (enable_intx)
  106                 reg_addr = &softs->pqi_reg->legacy_intr_mask_clr;
  107         else
  108                 reg_addr = &softs->pqi_reg->legacy_intr_mask_set;
  109 
  110         intx_mask = PCI_MEM_GET32(softs, reg_addr, PQI_LEGACY_INTR_MASK_CLR);
  111         intx_mask |= PQISRC_LEGACY_INTX_MASK;
  112         PCI_MEM_PUT32(softs, reg_addr, PQI_LEGACY_INTR_MASK_CLR ,intx_mask);
  113 
  114         DBG_FUNC("OUT\n");
  115 }
  116 
  117 /*
  118  * Function used to take exposed devices to OS as offline.
  119  */
  120 void
  121 pqisrc_take_devices_offline(pqisrc_softstate_t *softs)
  122 {
  123         pqi_scsi_dev_t *device = NULL;
  124         int i,j;
  125 
  126         DBG_FUNC("IN\n");
  127         for(i = 0; i < PQI_MAX_DEVICES; i++) {
  128                 for(j = 0; j < PQI_MAX_MULTILUN; j++) {
  129                         if(softs->device_list[i][j] == NULL)
  130                                 continue;
  131                         device = softs->device_list[i][j];
  132                         pqisrc_remove_device(softs, device);
  133                 }
  134         }
  135 
  136         DBG_FUNC("OUT\n");
  137 }
  138 
  139 /*
  140  * Function used to take adapter offline.
  141  */
  142 void
  143 pqisrc_take_ctrl_offline(pqisrc_softstate_t *softs)
  144 {
  145         DBG_FUNC("IN\n");
  146 
  147         softs->ctrl_online = false;
  148 
  149         int lockupcode = 0;
  150 
  151         if (SIS_IS_KERNEL_PANIC(softs)) {
  152                 lockupcode = PCI_MEM_GET32(softs, &softs->ioa_reg->mb[7], LEGACY_SIS_SRCV_OFFSET_MAILBOX_7);
  153                 DBG_ERR("Controller FW is not running, Lockup code = %x\n", lockupcode);
  154         }
  155         else {
  156                 pqisrc_trigger_nmi_sis(softs);
  157         }
  158 
  159         os_complete_outstanding_cmds_nodevice(softs);
  160         pqisrc_wait_for_rescan_complete(softs);
  161         pqisrc_take_devices_offline(softs);
  162 
  163         DBG_FUNC("OUT\n");
  164 }
  165 
  166 /*
  167  * Timer handler for the adapter heart-beat.
  168  */
  169 void
  170 pqisrc_heartbeat_timer_handler(pqisrc_softstate_t *softs)
  171 {
  172         uint8_t take_offline = false;
  173 
  174         DBG_FUNC("IN\n");
  175 
  176         if (CTRLR_HEARTBEAT_CNT(softs) == softs->prev_heartbeat_count) {
  177                 take_offline = true;
  178                 goto take_ctrl_offline;
  179         }
  180         softs->prev_heartbeat_count = CTRLR_HEARTBEAT_CNT(softs);
  181         DBG_INFO("CTRLR_HEARTBEAT_CNT(softs)  = %lx \
  182                 softs->prev_heartbeat_count = %lx\n",
  183                 CTRLR_HEARTBEAT_CNT(softs), softs->prev_heartbeat_count);
  184 
  185 take_ctrl_offline:
  186         if (take_offline){
  187                 DBG_ERR("controller is offline\n");
  188                 pqisrc_take_ctrl_offline(softs);
  189                 os_stop_heartbeat_timer(softs);
  190         }
  191         DBG_FUNC("OUT\n");
  192 }
  193 
  194 /*
  195  * Conditional variable management routine for internal commands.
  196  */
  197 int
  198 pqisrc_wait_on_condition(pqisrc_softstate_t *softs, rcb_t *rcb,
  199                                 uint32_t timeout_in_msec)
  200 {
  201         DBG_FUNC("IN\n");
  202 
  203         int ret = PQI_STATUS_SUCCESS;
  204 
  205         /* 1 msec = 500 usec * 2 */
  206         uint32_t loop_cnt = timeout_in_msec * 2;
  207         uint32_t i = 0;
  208 
  209         while (rcb->req_pending == true) {
  210                 OS_SLEEP(500); /* Micro sec */
  211                 /* Polling needed for FreeBSD : since ithread routine is not scheduled
  212                  * during bootup, we could use polling until interrupts are
  213                  * enabled (using 'if (cold)'to check for the boot time before
  214                  * interrupts are enabled). */
  215                 IS_POLLING_REQUIRED(softs);
  216 
  217                 if ((timeout_in_msec != TIMEOUT_INFINITE) && (i++ == loop_cnt)) {
  218                         DBG_ERR("ERR: Requested cmd timed out !!!\n");
  219                         ret = PQI_STATUS_TIMEOUT;
  220                         rcb->timedout = true;
  221                         break;
  222                 }
  223 
  224                 if (pqisrc_ctrl_offline(softs)) {
  225                         DBG_ERR("Controller is Offline");
  226                         ret = PQI_STATUS_FAILURE;
  227                         break;
  228                 }
  229 
  230         }
  231         rcb->req_pending = true;
  232 
  233         DBG_FUNC("OUT\n");
  234 
  235         return ret;
  236 }
  237 
  238 /* Function used to validate the device wwid. */
  239 boolean_t
  240 pqisrc_device_equal(pqi_scsi_dev_t *dev1,
  241         pqi_scsi_dev_t *dev2)
  242 {
  243         return dev1->wwid == dev2->wwid;
  244 }
  245 
  246 /* Function used to validate the device scsi3addr. */
  247 boolean_t
  248 pqisrc_scsi3addr_equal(uint8_t *scsi3addr1, uint8_t *scsi3addr2)
  249 {
  250         return memcmp(scsi3addr1, scsi3addr2, 8) == 0;
  251 }
  252 
  253 /* Function used to validate hba_lunid */
  254 boolean_t
  255 pqisrc_is_hba_lunid(uint8_t *scsi3addr)
  256 {
  257         return pqisrc_scsi3addr_equal(scsi3addr, (uint8_t*)RAID_CTLR_LUNID);
  258 }
  259 
  260 /* Function used to validate type of device */
  261 boolean_t
  262 pqisrc_is_logical_device(pqi_scsi_dev_t *device)
  263 {
  264         return !device->is_physical_device;
  265 }
  266 
  267 /* Function used to sanitize inquiry string */
  268 void
  269 pqisrc_sanitize_inquiry_string(unsigned char *s, int len)
  270 {
  271         boolean_t terminated = false;
  272 
  273         DBG_FUNC("IN\n");
  274 
  275         for (; len > 0; (--len, ++s)) {
  276                 if (*s == 0)
  277                         terminated = true;
  278                 if (terminated || *s < 0x20 || *s > 0x7e)
  279                         *s = ' ';
  280         }
  281 
  282         DBG_FUNC("OUT\n");
  283 }
  284 
  285 static char *raid_levels[] = {
  286         "RAID 0",
  287         "RAID 4",
  288         "RAID 1(1+0)",
  289         "RAID 5",
  290         "RAID 5+1",
  291         "RAID ADG",
  292         "RAID 1(ADM)",
  293 };
  294 
  295 /* Get the RAID level from the index */
  296 char *
  297 pqisrc_raidlevel_to_string(uint8_t raid_level)
  298 {
  299         DBG_FUNC("IN\n");
  300         if (raid_level < ARRAY_SIZE(raid_levels))
  301                 return raid_levels[raid_level];
  302         DBG_FUNC("OUT\n");
  303 
  304         return " ";
  305 }
  306 
  307 /* Debug routine for displaying device info */
  308 void pqisrc_display_device_info(pqisrc_softstate_t *softs,
  309         char *action, pqi_scsi_dev_t *device)
  310 {
  311         if (device->is_physical_device) {
  312                 DBG_NOTE("%s scsi BTL %d:%d:%d:  %.8s %.16s %-12s "
  313                 "SSDSmartPathCap%c En%c Exp%c qd=%d\n",
  314                 action,
  315                 device->bus,
  316                 device->target,
  317                 device->lun,
  318                 device->vendor,
  319                 device->model,
  320                 "Physical",
  321                 device->offload_config ? '+' : '-',
  322                 device->offload_enabled_pending ? '+' : '-',
  323                 device->expose_device ? '+' : '-',
  324                 device->queue_depth);
  325         } else if (device->devtype == RAID_DEVICE) {
  326                 DBG_NOTE("%s scsi BTL %d:%d:%d:  %.8s %.16s %-12s "
  327                 "SSDSmartPathCap%c En%c Exp%c qd=%d\n",
  328                 action,
  329                 device->bus,
  330                 device->target,
  331                 device->lun,
  332                 device->vendor,
  333                 device->model,
  334                 "Controller",
  335                 device->offload_config ? '+' : '-',
  336                 device->offload_enabled_pending ? '+' : '-',
  337                 device->expose_device ? '+' : '-',
  338                 device->queue_depth);
  339         } else if (device->devtype == CONTROLLER_DEVICE) {
  340                 DBG_NOTE("%s scsi BTL %d:%d:%d:  %.8s %.16s %-12s "
  341                 "SSDSmartPathCap%c En%c Exp%c qd=%d\n",
  342                 action,
  343                 device->bus,
  344                 device->target,
  345                 device->lun,
  346                 device->vendor,
  347                 device->model,
  348                 "External",
  349                 device->offload_config ? '+' : '-',
  350                 device->offload_enabled_pending ? '+' : '-',
  351                 device->expose_device ? '+' : '-',
  352                 device->queue_depth);
  353         } else {
  354                 DBG_NOTE("%s scsi BTL %d:%d:%d:  %.8s %.16s %-12s "
  355                 "SSDSmartPathCap%c En%c Exp%c qd=%d devtype=%d\n",
  356                 action,
  357                 device->bus,
  358                 device->target,
  359                 device->lun,
  360                 device->vendor,
  361                 device->model,
  362                 pqisrc_raidlevel_to_string(device->raid_level),
  363                 device->offload_config ? '+' : '-',
  364                 device->offload_enabled_pending ? '+' : '-',
  365                 device->expose_device ? '+' : '-',
  366                 device->queue_depth,
  367                 device->devtype);
  368         pqisrc_raidlevel_to_string(device->raid_level); /* To use this function */
  369         }
  370 }
  371 
  372 /* validate the structure sizes */
  373 void
  374 check_struct_sizes(void)
  375 {
  376 
  377     ASSERT(sizeof(SCSI3Addr_struct)== 2);
  378     ASSERT(sizeof(PhysDevAddr_struct) == 8);
  379     ASSERT(sizeof(LogDevAddr_struct)== 8);
  380     ASSERT(sizeof(LUNAddr_struct)==8);
  381     ASSERT(sizeof(RequestBlock_struct) == 20);
  382     ASSERT(sizeof(MoreErrInfo_struct)== 8);
  383     ASSERT(sizeof(ErrorInfo_struct)== 48);
  384     /* Checking the size of IOCTL_Command_struct for both
  385        64 bit and 32 bit system*/
  386     ASSERT(sizeof(IOCTL_Command_struct)== 86 ||
  387            sizeof(IOCTL_Command_struct)== 82);
  388     ASSERT(sizeof(struct bmic_host_wellness_driver_version)== 42);
  389     ASSERT(sizeof(struct bmic_host_wellness_time)== 20);
  390     ASSERT(sizeof(struct pqi_dev_adminq_cap)== 8);
  391     ASSERT(sizeof(struct admin_q_param)== 4);
  392     ASSERT(sizeof(struct pqi_registers)== 256);
  393     ASSERT(sizeof(struct ioa_registers)== 4128);
  394     ASSERT(sizeof(struct pqi_pref_settings)==4);
  395     ASSERT(sizeof(struct pqi_cap)== 20);
  396     ASSERT(sizeof(iu_header_t)== 4);
  397     ASSERT(sizeof(gen_adm_req_iu_t)== 64);
  398     ASSERT(sizeof(gen_adm_resp_iu_t)== 64);
  399     ASSERT(sizeof(op_q_params) == 9);
  400     ASSERT(sizeof(raid_path_error_info_elem_t)== 276);
  401     ASSERT(sizeof(aio_path_error_info_elem_t)== 276);
  402     ASSERT(sizeof(struct init_base_struct)== 24);
  403     ASSERT(sizeof(pqi_iu_layer_desc_t)== 16);
  404     ASSERT(sizeof(pqi_dev_cap_t)== 576);
  405     ASSERT(sizeof(pqi_aio_req_t)== 128);
  406     ASSERT(sizeof(pqisrc_raid_req_t)== 128);
  407     ASSERT(sizeof(pqi_raid_tmf_req_t)== 32);
  408     ASSERT(sizeof(pqi_aio_tmf_req_t)== 32);
  409     ASSERT(sizeof(struct pqi_io_response)== 16);
  410     ASSERT(sizeof(struct sense_header_scsi)== 8);
  411     ASSERT(sizeof(reportlun_header_t)==8);
  412     ASSERT(sizeof(reportlun_ext_entry_t)== 24);
  413     ASSERT(sizeof(reportlun_data_ext_t)== 32);
  414     ASSERT(sizeof(raidmap_data_t)==8);
  415     ASSERT(sizeof(pqisrc_raid_map_t)== 8256);
  416     ASSERT(sizeof(bmic_ident_ctrl_t)== 325);
  417     ASSERT(sizeof(bmic_ident_physdev_t)==2048);
  418 
  419 }
  420 
  421 uint32_t
  422 pqisrc_count_num_scsi_active_requests_on_dev(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device)
  423 {
  424         uint32_t i, active_io = 0;
  425         rcb_t* rcb;
  426 
  427         for(i = 1; i <= softs->max_outstanding_io; i++) {
  428                 rcb = &softs->rcb[i];
  429                 if(rcb && IS_OS_SCSICMD(rcb) && (rcb->dvp == device) && rcb->req_pending) {
  430                         active_io++;
  431                 }
  432         }
  433         return active_io;
  434 }
  435 
  436 void
  437 check_device_pending_commands_to_complete(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device)
  438 {
  439         uint32_t tag = softs->max_outstanding_io, active_requests;
  440         uint64_t timeout = 0, delay_in_usec = 1000; //In micro Seconds
  441         rcb_t* rcb;
  442 
  443         DBG_FUNC("IN\n");
  444 
  445         active_requests = pqisrc_count_num_scsi_active_requests_on_dev(softs, device);
  446 
  447         DBG_WARN("Device Outstanding IO count = %u\n", active_requests);
  448 
  449         if(!active_requests)
  450                 return;
  451 
  452         do {
  453                 rcb = &softs->rcb[tag];
  454                 if(rcb && IS_OS_SCSICMD(rcb) && (rcb->dvp == device) && rcb->req_pending) {
  455                         OS_BUSYWAIT(delay_in_usec);
  456                         timeout += delay_in_usec;
  457                 }
  458                 else
  459                         tag--;
  460                 if(timeout >= PQISRC_PENDING_IO_TIMEOUT_USEC) {
  461                         DBG_WARN("timed out waiting for pending IO\n");
  462                         return;
  463                 }
  464         } while(tag);
  465 
  466 }
  467 
  468 inline uint64_t
  469 pqisrc_increment_device_active_io(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device)
  470 {
  471 #if PQISRC_DEVICE_IO_COUNTER
  472         /*Increment device active io count by one*/
  473         return OS_ATOMIC64_INC(&device->active_requests);
  474 #endif
  475 }
  476 
  477 inline uint64_t
  478 pqisrc_decrement_device_active_io(pqisrc_softstate_t *softs,  pqi_scsi_dev_t *device)
  479 {
  480 #if PQISRC_DEVICE_IO_COUNTER
  481         /*Decrement device active io count by one*/
  482         return OS_ATOMIC64_DEC(&device->active_requests);
  483 #endif
  484 }
  485 
  486 inline void
  487 pqisrc_init_device_active_io(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device)
  488 {
  489 #if PQISRC_DEVICE_IO_COUNTER
  490         /* Reset device count to Zero */
  491         OS_ATOMIC64_INIT(&device->active_requests, 0);
  492 #endif
  493 }
  494 
  495 inline uint64_t
  496 pqisrc_read_device_active_io(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device)
  497 {
  498 #if PQISRC_DEVICE_IO_COUNTER
  499         /* read device active count*/
  500         return OS_ATOMIC64_READ(&device->active_requests);
  501 #endif
  502 }
  503 
  504 void
  505 pqisrc_wait_for_device_commands_to_complete(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device)
  506 {
  507         uint64_t timeout_in_usec = 0, delay_in_usec = 1000; //In microseconds
  508 
  509         DBG_FUNC("IN\n");
  510 
  511         if(!softs->ctrl_online)
  512                 return;
  513 
  514 #if PQISRC_DEVICE_IO_COUNTER
  515         DBG_NOTE("Device Outstanding IO count = %ld\n", pqisrc_read_device_active_io(softs, device));
  516 
  517         while(pqisrc_read_device_active_io(softs, device)) {
  518                 OS_BUSYWAIT(delay_in_usec); // In microseconds
  519                 if(!softs->ctrl_online) {
  520                         DBG_WARN("Controller Offline was detected.\n");
  521                 }
  522                 timeout_in_usec += delay_in_usec;
  523                 if(timeout_in_usec >= PQISRC_PENDING_IO_TIMEOUT_USEC) {
  524                         DBG_WARN("timed out waiting for pending IO. DeviceOutStandingIo's=%ld\n",
  525                                  pqisrc_read_device_active_io(softs, device));
  526                         return;
  527                 }
  528         }
  529 #else
  530         check_device_pending_commands_to_complete(softs, device);
  531 #endif
  532 }

Cache object: 96106da89923b279ebf31ca69228c0df


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.