Add sysctls in ahd(4) in order to keep track of different classes of
errors. So far 3 different classes are present (correctable, uncorrectable and fatal) but more can be added easilly. Obtained from: Sandvine Incorporated Reviewed by: emase, gibbs Sponsored by: Sandvine Incorporated MFC: 2 weeks
This commit is contained in:
parent
5fe8543b99
commit
0e3418f9cf
@ -134,6 +134,7 @@ ahd_pci_attach(device_t dev)
|
||||
return (error);
|
||||
}
|
||||
|
||||
ahd_sysctl(ahd);
|
||||
ahd_attach(ahd);
|
||||
return (0);
|
||||
}
|
||||
@ -198,6 +199,7 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
|
||||
bus_release_resource(ahd->dev_softc, regs_type,
|
||||
regs_id, regs);
|
||||
regs = NULL;
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
} else {
|
||||
command &= ~PCIM_CMD_PORTEN;
|
||||
aic_pci_write_config(ahd->dev_softc,
|
||||
@ -214,6 +216,7 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
|
||||
if (regs == NULL) {
|
||||
device_printf(ahd->dev_softc,
|
||||
"can't allocate register resources\n");
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
return (ENOMEM);
|
||||
}
|
||||
ahd->tags[0] = rman_get_bustag(regs);
|
||||
@ -226,6 +229,7 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
|
||||
if (regs2 == NULL) {
|
||||
device_printf(ahd->dev_softc,
|
||||
"can't allocate register resources\n");
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
return (ENOMEM);
|
||||
}
|
||||
ahd->tags[1] = rman_get_bustag(regs2);
|
||||
|
@ -401,6 +401,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd)
|
||||
if (scb == NULL) {
|
||||
printf("%s: Warning - GSFIFO SCB %d invalid\n",
|
||||
ahd_name(ahd), scbid);
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@ -525,6 +526,7 @@ rescan_fifos:
|
||||
if (scb == NULL) {
|
||||
printf("%s: Warning - DMA-up and complete "
|
||||
"SCB %d invalid\n", ahd_name(ahd), scbid);
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
continue;
|
||||
}
|
||||
hscb_ptr = (uint8_t *)scb->hscb;
|
||||
@ -546,6 +548,7 @@ rescan_fifos:
|
||||
if (scb == NULL) {
|
||||
printf("%s: Warning - Complete Qfrz SCB %d invalid\n",
|
||||
ahd_name(ahd), scbid);
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -563,6 +566,7 @@ rescan_fifos:
|
||||
if (scb == NULL) {
|
||||
printf("%s: Warning - Complete SCB %d invalid\n",
|
||||
ahd_name(ahd), scbid);
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -870,6 +874,7 @@ ahd_run_qoutfifo(struct ahd_softc *ahd)
|
||||
"(cmdcmplt)\nQOUTPOS = %d\n",
|
||||
ahd_name(ahd), scb_index,
|
||||
ahd->qoutfifonext);
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
ahd_dump_card_state(ahd);
|
||||
} else if ((completion->sg_status & SG_STATUS_VALID) != 0) {
|
||||
ahd_handle_scb_status(ahd, scb);
|
||||
@ -897,9 +902,11 @@ ahd_handle_hwerrint(struct ahd_softc *ahd)
|
||||
|
||||
error = ahd_inb(ahd, ERROR);
|
||||
for (i = 0; i < num_errors; i++) {
|
||||
if ((error & ahd_hard_errors[i].errno) != 0)
|
||||
if ((error & ahd_hard_errors[i].errno) != 0) {
|
||||
printf("%s: hwerrint, %s\n",
|
||||
ahd_name(ahd), ahd_hard_errors[i].errmesg);
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
}
|
||||
}
|
||||
|
||||
ahd_dump_card_state(ahd);
|
||||
@ -990,6 +997,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
ahd_name(ahd));
|
||||
ahd_dump_card_state(ahd);
|
||||
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
break;
|
||||
case STATUS_OVERRUN:
|
||||
{
|
||||
@ -1005,6 +1013,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
printf("SCB %d Packetized Status Overrun", scbid);
|
||||
ahd_dump_card_state(ahd);
|
||||
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
break;
|
||||
}
|
||||
case CFG4ISTAT_INTR:
|
||||
@ -1017,6 +1026,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
if (scb == NULL) {
|
||||
ahd_dump_card_state(ahd);
|
||||
printf("CFG4ISTAT: Free SCB %d referenced", scbid);
|
||||
AHD_FATAL_ERROR(ahd);
|
||||
panic("For safety");
|
||||
}
|
||||
ahd_outq(ahd, HADDR, scb->sense_busaddr);
|
||||
@ -1044,6 +1054,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
case P_MESGIN:
|
||||
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
|
||||
printf("%s: Issued Bus Reset.\n", ahd_name(ahd));
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
break;
|
||||
case P_COMMAND:
|
||||
{
|
||||
@ -1068,6 +1079,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
scbid = ahd_get_scbptr(ahd);
|
||||
scb = ahd_lookup_scb(ahd, scbid);
|
||||
if (scb == NULL) {
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
printf("Invalid phase with no valid SCB. "
|
||||
"Resetting bus.\n");
|
||||
ahd_reset_channel(ahd, 'A',
|
||||
@ -1127,6 +1139,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
#ifdef AHD_DEBUG
|
||||
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
|
||||
ahd_print_path(ahd, scb);
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
printf("Unexpected command phase from "
|
||||
"packetized target\n");
|
||||
}
|
||||
@ -1214,6 +1227,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
&& bus_phase != P_MESGOUT) {
|
||||
printf("ahd_intr: HOST_MSG_LOOP bad "
|
||||
"phase 0x%x\n", bus_phase);
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
/*
|
||||
* Probably transitioned to bus free before
|
||||
* we got here. Just punt the message.
|
||||
@ -1316,6 +1330,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
ahd_name(ahd), 'A',
|
||||
SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
|
||||
lastphase, ahd_inb(ahd, SCSISIGI));
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
break;
|
||||
}
|
||||
case MISSED_BUSFREE:
|
||||
@ -1328,6 +1343,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
ahd_name(ahd), 'A',
|
||||
SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
|
||||
lastphase, ahd_inb(ahd, SCSISIGI));
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
ahd_restart(ahd);
|
||||
return;
|
||||
}
|
||||
@ -1387,6 +1403,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
devinfo.lun);
|
||||
scbid = ahd_get_scbptr(ahd);
|
||||
scb = ahd_lookup_scb(ahd, scbid);
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
if (scb != NULL
|
||||
&& (scb->flags & SCB_RECOVERY_SCB) != 0)
|
||||
/*
|
||||
@ -1570,11 +1587,13 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
|
||||
|
||||
printf("%s: SCSI offset overrun detected. Resetting bus.\n",
|
||||
ahd_name(ahd));
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
|
||||
} else if ((status & SCSIRSTI) != 0) {
|
||||
|
||||
printf("%s: Someone reset channel A\n", ahd_name(ahd));
|
||||
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE);
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
} else if ((status & SCSIPERR) != 0) {
|
||||
|
||||
/* Make sure the sequencer is in a safe location. */
|
||||
@ -1619,6 +1638,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
|
||||
"valid during SELTO scb(0x%x)\n",
|
||||
ahd_name(ahd), scbid);
|
||||
ahd_dump_card_state(ahd);
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
} else {
|
||||
struct ahd_devinfo devinfo;
|
||||
#ifdef AHD_DEBUG
|
||||
@ -1654,6 +1674,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
|
||||
} else if (status3 != 0) {
|
||||
printf("%s: SCSI Cell parity error SSTAT3 == 0x%x\n",
|
||||
ahd_name(ahd), status3);
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
ahd_outb(ahd, CLRSINT3, status3);
|
||||
} else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) {
|
||||
|
||||
@ -1712,6 +1733,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
|
||||
"during unexpected busfree\n",
|
||||
ahd_name(ahd), scbid, mode);
|
||||
packetized = 0;
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
} else
|
||||
packetized = (scb->flags & SCB_PACKETIZED) != 0;
|
||||
clear_fifo = 1;
|
||||
@ -1856,6 +1878,7 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
|
||||
ahd_scsisigi_print(curphase, &cur_col, 50);
|
||||
ahd_perrdiag_print(perrdiag, &cur_col, 50);
|
||||
printf("\n");
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
ahd_dump_card_state(ahd);
|
||||
}
|
||||
|
||||
@ -1864,6 +1887,7 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
|
||||
printf("%s: Gross protocol error during incoming "
|
||||
"packet. lqistat1 == 0x%x. Resetting bus.\n",
|
||||
ahd_name(ahd), lqistat1);
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
}
|
||||
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
|
||||
return;
|
||||
@ -1891,6 +1915,7 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
|
||||
*/
|
||||
ahd_outb(ahd, LQCTL2, LQIRETRY);
|
||||
printf("LQIRetry for LQICRCI_LQ to release ACK\n");
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
} else if ((lqistat1 & LQICRCI_NLQ) != 0) {
|
||||
/*
|
||||
* We detected a CRC error in a NON-LQ packet.
|
||||
@ -1942,6 +1967,7 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
|
||||
if (scb == NULL) {
|
||||
printf("%s: No SCB valid for LQICRC_NLQ. "
|
||||
"Resetting bus\n", ahd_name(ahd));
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
|
||||
return;
|
||||
}
|
||||
@ -1999,9 +2025,11 @@ ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1)
|
||||
&& (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) {
|
||||
if ((lqistat1 & LQIPHASE_LQ) != 0) {
|
||||
printf("LQIRETRY for LQIPHASE_LQ\n");
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
ahd_outb(ahd, LQCTL2, LQIRETRY);
|
||||
} else if ((lqistat1 & LQIPHASE_NLQ) != 0) {
|
||||
printf("LQIRETRY for LQIPHASE_NLQ\n");
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
ahd_outb(ahd, LQCTL2, LQIRETRY);
|
||||
} else
|
||||
panic("ahd_handle_lqiphase_error: No phase errors\n");
|
||||
@ -2010,6 +2038,7 @@ ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1)
|
||||
ahd_unpause(ahd);
|
||||
} else {
|
||||
printf("Reseting Channel for LQI Phase error\n");
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
ahd_dump_card_state(ahd);
|
||||
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
|
||||
}
|
||||
@ -2099,6 +2128,7 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
|
||||
ahd_print_path(ahd, scb);
|
||||
printf("Probable outgoing LQ CRC error. "
|
||||
"Retrying command\n");
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
}
|
||||
scb->crc_retry_count++;
|
||||
} else {
|
||||
@ -2134,6 +2164,7 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
|
||||
scb = ahd_lookup_scb(ahd, scbid);
|
||||
ahd_print_path(ahd, scb);
|
||||
printf("Unexpected PKT busfree condition\n");
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
ahd_dump_card_state(ahd);
|
||||
ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A',
|
||||
SCB_GET_LUN(scb), SCB_GET_TAG(scb),
|
||||
@ -2143,6 +2174,7 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
|
||||
return (1);
|
||||
}
|
||||
printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd));
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
ahd_dump_card_state(ahd);
|
||||
/* Restart the sequencer. */
|
||||
return (1);
|
||||
@ -2421,6 +2453,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
||||
ahd_lookup_phase_entry(lastphase)->phasemsg,
|
||||
aborted,
|
||||
ahd_inw(ahd, PRGMCNT));
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
ahd_dump_card_state(ahd);
|
||||
if (lastphase != P_BUSFREE)
|
||||
ahd_force_renegotiation(ahd, &devinfo);
|
||||
@ -2456,6 +2489,7 @@ ahd_handle_proto_violation(struct ahd_softc *ahd)
|
||||
ahd_print_devinfo(ahd, &devinfo);
|
||||
printf("Target did not send an IDENTIFY message. "
|
||||
"LASTPHASE = 0x%x.\n", lastphase);
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
scb = NULL;
|
||||
} else if (scb == NULL) {
|
||||
/*
|
||||
@ -2464,12 +2498,14 @@ ahd_handle_proto_violation(struct ahd_softc *ahd)
|
||||
*/
|
||||
ahd_print_devinfo(ahd, &devinfo);
|
||||
printf("No SCB found during protocol violation\n");
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
goto proto_violation_reset;
|
||||
} else {
|
||||
aic_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
|
||||
if ((seq_flags & NO_CDB_SENT) != 0) {
|
||||
ahd_print_path(ahd, scb);
|
||||
printf("No or incomplete CDB sent to device.\n");
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
} else if ((ahd_inb_scbram(ahd, SCB_CONTROL)
|
||||
& STATUS_RCVD) == 0) {
|
||||
/*
|
||||
@ -2484,6 +2520,7 @@ ahd_handle_proto_violation(struct ahd_softc *ahd)
|
||||
} else {
|
||||
ahd_print_path(ahd, scb);
|
||||
printf("Unknown protocol violation.\n");
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
ahd_dump_card_state(ahd);
|
||||
}
|
||||
}
|
||||
@ -2499,6 +2536,7 @@ proto_violation_reset:
|
||||
found = ahd_reset_channel(ahd, 'A', TRUE);
|
||||
printf("%s: Issued Channel %c Bus Reset. "
|
||||
"%d SCBs aborted\n", ahd_name(ahd), 'A', found);
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
} else {
|
||||
/*
|
||||
* Leave the selection hardware off in case
|
||||
@ -2521,6 +2559,7 @@ proto_violation_reset:
|
||||
}
|
||||
printf("Protocol violation %s. Attempting to abort.\n",
|
||||
ahd_lookup_phase_entry(curphase)->phasemsg);
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2602,6 +2641,7 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
|
||||
"%s: First Instruction 0x%x now 0x%x\n",
|
||||
ahd_name(ahd), ahd_name(ahd), first_instr,
|
||||
seqaddr);
|
||||
AHD_FATAL_ERROR(ahd);
|
||||
ahd_dump_card_state(ahd);
|
||||
panic("critical section loop");
|
||||
}
|
||||
@ -3566,6 +3606,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
} else if (scb == NULL) {
|
||||
printf("%s: WARNING. No pending message for "
|
||||
"I_T msgin. Issuing NO-OP\n", ahd_name(ahd));
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_NOOP;
|
||||
ahd->msgout_len++;
|
||||
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||
@ -3596,6 +3637,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
ahd->msgout_len++;
|
||||
ahd_print_path(ahd, scb);
|
||||
printf("Bus Device Reset Message Sent\n");
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
/*
|
||||
* Clear our selection hardware in advance of
|
||||
* the busfree. We may have an entry in the waiting
|
||||
@ -3615,6 +3657,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
ahd_print_path(ahd, scb);
|
||||
printf("Abort%s Message Sent\n",
|
||||
(scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
/*
|
||||
* Clear our selection hardware in advance of
|
||||
* the busfree. We may have an entry in the waiting
|
||||
@ -3638,6 +3681,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
"does not have a waiting message\n");
|
||||
printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
|
||||
devinfo->target_mask);
|
||||
AHD_FATAL_ERROR(ahd);
|
||||
panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x "
|
||||
"SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control,
|
||||
ahd_inb_scbram(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT),
|
||||
@ -5129,9 +5173,11 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
lun, AC_SENT_BDR, NULL);
|
||||
|
||||
if (message != NULL
|
||||
&& (verbose_level <= bootverbose))
|
||||
&& (verbose_level <= bootverbose)) {
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd),
|
||||
message, devinfo->channel, devinfo->target, found);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef AHD_TARGET_MODE
|
||||
@ -5509,6 +5555,7 @@ ahd_reset(struct ahd_softc *ahd, int reinit)
|
||||
if (wait == 0) {
|
||||
printf("%s: WARNING - Failed chip reset! "
|
||||
"Trying to initialize anyway.\n", ahd_name(ahd));
|
||||
AHD_FATAL_ERROR(ahd);
|
||||
}
|
||||
ahd_outb(ahd, HCNTRL, ahd->pause);
|
||||
|
||||
@ -5630,6 +5677,7 @@ ahd_init_scbdata(struct ahd_softc *ahd)
|
||||
scb_data->maxhscbs = ahd_probe_scbs(ahd);
|
||||
if (scb_data->maxhscbs == 0) {
|
||||
printf("%s: No SCB space found\n", ahd_name(ahd));
|
||||
AHD_FATAL_ERROR(ahd);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
@ -6474,6 +6522,7 @@ ahd_init(struct ahd_softc *ahd)
|
||||
printf("%s: WARNING. Termination is not configured correctly.\n"
|
||||
"%s: WARNING. SCSI bus operations may FAIL.\n",
|
||||
ahd_name(ahd), ahd_name(ahd));
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
}
|
||||
init_done:
|
||||
ahd_restart(ahd);
|
||||
@ -6830,6 +6879,7 @@ ahd_default_config(struct ahd_softc *ahd)
|
||||
if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
|
||||
printf("%s: unable to allocate ahd_tmode_tstate. "
|
||||
"Failing attach\n", ahd_name(ahd));
|
||||
AHD_FATAL_ERROR(ahd);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
@ -6909,6 +6959,7 @@ ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc)
|
||||
if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
|
||||
printf("%s: unable to allocate ahd_tmode_tstate. "
|
||||
"Failing attach\n", ahd_name(ahd));
|
||||
AHD_FATAL_ERROR(ahd);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
@ -7135,6 +7186,7 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd)
|
||||
if (maxloops == 0) {
|
||||
printf("Infinite interrupt loop, INTSTAT = %x",
|
||||
ahd_inb(ahd, INTSTAT));
|
||||
AHD_FATAL_ERROR(ahd);
|
||||
}
|
||||
ahd->qfreeze_cnt++;
|
||||
ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt);
|
||||
@ -7440,6 +7492,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
|
||||
if (scb == NULL) {
|
||||
printf("qinpos = %d, SCB index = %d\n",
|
||||
qinpos, ahd->qinfifo[qinpos]);
|
||||
AHD_FATAL_ERROR(ahd);
|
||||
panic("Loop 1\n");
|
||||
}
|
||||
|
||||
@ -8195,20 +8248,26 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
|
||||
switch (SIU_PKTFAIL_CODE(siu)) {
|
||||
case SIU_PFC_NONE:
|
||||
printf("No packet failure found\n");
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
break;
|
||||
case SIU_PFC_CIU_FIELDS_INVALID:
|
||||
printf("Invalid Command IU Field\n");
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
break;
|
||||
case SIU_PFC_TMF_NOT_SUPPORTED:
|
||||
printf("TMF not supportd\n");
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
break;
|
||||
case SIU_PFC_TMF_FAILED:
|
||||
printf("TMF failed\n");
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
break;
|
||||
case SIU_PFC_INVALID_TYPE_CODE:
|
||||
printf("Invalid L_Q Type code\n");
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
break;
|
||||
case SIU_PFC_ILLEGAL_REQUEST:
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
printf("Illegal request\n");
|
||||
default:
|
||||
break;
|
||||
@ -9281,6 +9340,7 @@ ahd_recover_commands(struct ahd_softc *ahd)
|
||||
|
||||
printf("%s: Recovery Initiated - Card was %spaused\n", ahd_name(ahd),
|
||||
was_paused ? "" : "not ");
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
ahd_dump_card_state(ahd);
|
||||
|
||||
ahd_pause_and_flushwork(ahd);
|
||||
@ -9507,6 +9567,7 @@ ahd_other_scb_timeout(struct ahd_softc *ahd, struct scb *scb,
|
||||
(scb->flags & SCB_OTHERTCL_TIMEOUT) != 0
|
||||
? " again\n" : "\n");
|
||||
|
||||
AHD_UNCORRECTABLE_ERROR(ahd);
|
||||
newtimeout = aic_get_timeout(scb);
|
||||
scb->flags |= SCB_OTHERTCL_TIMEOUT;
|
||||
found = 0;
|
||||
@ -9929,6 +9990,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
|
||||
if (lstate != NULL) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
printf("Lun already enabled\n");
|
||||
AHD_CORRECTABLE_ERROR(ahd);
|
||||
ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
|
||||
return;
|
||||
}
|
||||
|
@ -1061,6 +1061,27 @@ typedef enum {
|
||||
#define AHD_MODE_UNKNOWN_MSK AHD_MK_MSK(AHD_MODE_UNKNOWN)
|
||||
#define AHD_MODE_ANY_MSK (~0)
|
||||
|
||||
typedef enum {
|
||||
AHD_SYSCTL_ROOT,
|
||||
AHD_SYSCTL_SUMMARY,
|
||||
AHD_SYSCTL_DEBUG,
|
||||
AHD_SYSCTL_NUMBER
|
||||
} ahd_sysctl_types_t;
|
||||
|
||||
typedef enum {
|
||||
AHD_ERRORS_CORRECTABLE,
|
||||
AHD_ERRORS_UNCORRECTABLE,
|
||||
AHD_ERRORS_FATAL,
|
||||
AHD_ERRORS_NUMBER
|
||||
} ahd_sysctl_errors_t;
|
||||
|
||||
#define AHD_CORRECTABLE_ERROR(sc) \
|
||||
(((sc)->summerr[AHD_ERRORS_CORRECTABLE])++)
|
||||
#define AHD_UNCORRECTABLE_ERROR(sc) \
|
||||
(((sc)->summerr[AHD_ERRORS_UNCORRECTABLE])++)
|
||||
#define AHD_FATAL_ERROR(sc) \
|
||||
(((sc)->summerr[AHD_ERRORS_FATAL])++)
|
||||
|
||||
typedef uint8_t ahd_mode_state;
|
||||
|
||||
typedef void ahd_callback_t (void *);
|
||||
@ -1158,6 +1179,13 @@ struct ahd_softc {
|
||||
uint32_t cmdcmplt_counts[AHD_STAT_BUCKETS];
|
||||
uint32_t cmdcmplt_total;
|
||||
|
||||
/*
|
||||
* Errors statistics and printouts.
|
||||
*/
|
||||
struct sysctl_ctx_list sysctl_ctx[AHD_SYSCTL_NUMBER];
|
||||
struct sysctl_oid *sysctl_tree[AHD_SYSCTL_NUMBER];
|
||||
u_int summerr[AHD_ERRORS_NUMBER];
|
||||
|
||||
/*
|
||||
* Card characteristics
|
||||
*/
|
||||
|
@ -77,6 +77,63 @@ static int ahd_create_path(struct ahd_softc *ahd,
|
||||
char channel, u_int target, u_int lun,
|
||||
struct cam_path **path);
|
||||
|
||||
static const char *ahd_sysctl_node_elements[] = {
|
||||
"root",
|
||||
"summary",
|
||||
"debug"
|
||||
};
|
||||
|
||||
static const char *ahd_sysctl_node_descriptions[] = {
|
||||
"root error collection for aic79xx controllers",
|
||||
"summary collection for aic79xx controllers",
|
||||
"debug collection for aic79xx controllers"
|
||||
};
|
||||
|
||||
static const char *ahd_sysctl_errors_elements[] = {
|
||||
"Cerrors",
|
||||
"Uerrors",
|
||||
"Ferrors"
|
||||
};
|
||||
|
||||
static const char *ahd_sysctl_errors_descriptions[] = {
|
||||
"Correctable errors",
|
||||
"Uncorrectable errors",
|
||||
"Fatal errors"
|
||||
};
|
||||
|
||||
static int
|
||||
ahd_set_debugcounters(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct ahd_softc *sc;
|
||||
int error, tmpv;
|
||||
|
||||
tmpv = 0;
|
||||
sc = arg1;
|
||||
error = sysctl_handle_int(oidp, &tmpv, 0, req);
|
||||
if (error != 0 || req->newptr == NULL)
|
||||
return (error);
|
||||
if (tmpv < 0 || tmpv >= AHD_ERRORS_NUMBER)
|
||||
return (EINVAL);
|
||||
sc->summerr[arg2] = tmpv;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ahd_clear_allcounters(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct ahd_softc *sc;
|
||||
int error, tmpv;
|
||||
|
||||
tmpv = 0;
|
||||
sc = arg1;
|
||||
error = sysctl_handle_int(oidp, &tmpv, 0, req);
|
||||
if (error != 0 || req->newptr == NULL)
|
||||
return (error);
|
||||
if (tmpv != 0)
|
||||
bzero(sc->summerr, sizeof(sc->summerr));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ahd_create_path(struct ahd_softc *ahd, char channel, u_int target,
|
||||
u_int lun, struct cam_path **path)
|
||||
@ -88,6 +145,48 @@ ahd_create_path(struct ahd_softc *ahd, char channel, u_int target,
|
||||
path_id, target, lun));
|
||||
}
|
||||
|
||||
void
|
||||
ahd_sysctl(struct ahd_softc *ahd)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < AHD_SYSCTL_NUMBER; i++)
|
||||
sysctl_ctx_init(&ahd->sysctl_ctx[i]);
|
||||
|
||||
ahd->sysctl_tree[AHD_SYSCTL_ROOT] =
|
||||
SYSCTL_ADD_NODE(&ahd->sysctl_ctx[AHD_SYSCTL_ROOT],
|
||||
SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO,
|
||||
device_get_nameunit(ahd->dev_softc), CTLFLAG_RD, 0,
|
||||
ahd_sysctl_node_descriptions[AHD_SYSCTL_ROOT]);
|
||||
SYSCTL_ADD_PROC(&ahd->sysctl_ctx[AHD_SYSCTL_ROOT],
|
||||
SYSCTL_CHILDREN(ahd->sysctl_tree[AHD_SYSCTL_ROOT]),
|
||||
OID_AUTO, "clear", CTLTYPE_UINT | CTLFLAG_RW, ahd,
|
||||
0, ahd_clear_allcounters, "IU",
|
||||
"Clear all counters");
|
||||
|
||||
for (i = AHD_SYSCTL_SUMMARY; i < AHD_SYSCTL_NUMBER; i++)
|
||||
ahd->sysctl_tree[i] =
|
||||
SYSCTL_ADD_NODE(&ahd->sysctl_ctx[i],
|
||||
SYSCTL_CHILDREN(ahd->sysctl_tree[AHD_SYSCTL_ROOT]),
|
||||
OID_AUTO, ahd_sysctl_node_elements[i],
|
||||
CTLFLAG_RD, 0,
|
||||
ahd_sysctl_node_descriptions[i]);
|
||||
|
||||
for (i = AHD_ERRORS_CORRECTABLE; i < AHD_ERRORS_NUMBER; i++) {
|
||||
SYSCTL_ADD_UINT(&ahd->sysctl_ctx[AHD_SYSCTL_SUMMARY],
|
||||
SYSCTL_CHILDREN(ahd->sysctl_tree[AHD_SYSCTL_SUMMARY]),
|
||||
OID_AUTO, ahd_sysctl_errors_elements[i],
|
||||
CTLFLAG_RD, &ahd->summerr[i], i,
|
||||
ahd_sysctl_errors_descriptions[i]);
|
||||
SYSCTL_ADD_PROC(&ahd->sysctl_ctx[AHD_SYSCTL_DEBUG],
|
||||
SYSCTL_CHILDREN(ahd->sysctl_tree[AHD_SYSCTL_DEBUG]),
|
||||
OID_AUTO, ahd_sysctl_errors_elements[i],
|
||||
CTLFLAG_RW | CTLTYPE_UINT, ahd, i,
|
||||
ahd_set_debugcounters, "IU",
|
||||
ahd_sysctl_errors_descriptions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ahd_map_int(struct ahd_softc *ahd)
|
||||
{
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#define AIC_PCI_CONFIG 1
|
||||
#include <machine/bus.h>
|
||||
@ -259,6 +260,7 @@ void ahd_platform_free(struct ahd_softc *ahd);
|
||||
int ahd_map_int(struct ahd_softc *ahd);
|
||||
int ahd_attach(struct ahd_softc *);
|
||||
int ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd);
|
||||
void ahd_sysctl(struct ahd_softc *ahd);
|
||||
int ahd_detach(device_t);
|
||||
#define ahd_platform_init(arg)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user