From owner-svn-src-all@FreeBSD.ORG Tue Nov 3 11:19:06 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 153D9106566B; Tue, 3 Nov 2009 11:19:06 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 033EA8FC0C; Tue, 3 Nov 2009 11:19:06 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id nA3BJ5I7090045; Tue, 3 Nov 2009 11:19:05 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id nA3BJ50K090039; Tue, 3 Nov 2009 11:19:05 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <200911031119.nA3BJ50K090039@svn.freebsd.org> From: Alexander Motin Date: Tue, 3 Nov 2009 11:19:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r198849 - in head/sys/cam: . ata X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Nov 2009 11:19:06 -0000 Author: mav Date: Tue Nov 3 11:19:05 2009 New Revision: 198849 URL: http://svn.freebsd.org/changeset/base/198849 Log: MFp4: Improve reporting ATA Status error details. Modified: head/sys/cam/ata/ata_all.c head/sys/cam/ata/ata_all.h head/sys/cam/cam.c head/sys/cam/cam.h head/sys/cam/cam_periph.c Modified: head/sys/cam/ata/ata_all.c ============================================================================== --- head/sys/cam/ata/ata_all.c Tue Nov 3 09:28:45 2009 (r198848) +++ head/sys/cam/ata/ata_all.c Tue Nov 3 11:19:05 2009 (r198849) @@ -68,6 +68,185 @@ ata_version(int ver) return 0; } +char * +ata_op_string(struct ata_cmd *cmd) +{ + + switch (cmd->command) { + case 0x00: return ("NOP"); + case 0x03: return ("CFA_REQUEST_EXTENDED_ERROR"); + case 0x08: return ("DEVICE_RESET"); + case 0x20: return ("READ"); + case 0x24: return ("READ48"); + case 0x25: return ("READ_DMA48"); + case 0x26: return ("READ_DMA_QUEUED48"); + case 0x27: return ("READ_NATIVE_MAX_ADDRESS48"); + case 0x29: return ("READ_MUL48"); + case 0x2a: return ("READ_STREAM_DMA48"); + case 0x2b: return ("READ_STREAM48"); + case 0x2f: return ("READ_LOG_EXT"); + case 0x30: return ("WRITE"); + case 0x34: return ("WRITE48"); + case 0x35: return ("WRITE_DMA48"); + case 0x36: return ("WRITE_DMA_QUEUED48"); + case 0x37: return ("SET_MAX_ADDRESS48"); + case 0x39: return ("WRITE_MUL48"); + case 0x3a: return ("WRITE_STREAM_DMA48"); + case 0x3b: return ("WRITE_STREAM48"); + case 0x3d: return ("WRITE_DMA_FUA"); + case 0x3e: return ("WRITE_DMA_FUA48"); + case 0x3f: return ("WRITE_LOG_EXT"); + case 0x40: return ("READ_VERIFY"); + case 0x42: return ("READ_VERIFY48"); + case 0x51: return ("CONFIGURE_STREAM"); + case 0x60: return ("READ_FPDMA_QUEUED"); + case 0x61: return ("WRITE_FPDMA_QUEUED"); + case 0x70: return ("SEEK"); + case 0x87: return ("CFA_TRANSLATE_SECTOR"); + case 0x90: return ("EXECUTE_DEVICE_DIAGNOSTIC"); + case 0x92: return ("DOWNLOAD_MICROCODE"); + case 0xa0: return ("PACKET"); + case 0xa1: return ("ATAPI_IDENTIFY"); + case 0xa2: return ("SERVICE"); + case 0xb0: return ("SMART"); + case 0xb1: return ("DEVICE CONFIGURATION"); + case 0xc0: return ("CFA_ERASE"); + case 0xc4: return ("READ_MUL"); + case 0xc5: return ("WRITE_MUL"); + case 0xc6: return ("SET_MULTI"); + case 0xc7: return ("READ_DMA_QUEUED"); + case 0xc8: return ("READ_DMA"); + case 0xca: return ("WRITE_DMA"); + case 0xcc: return ("WRITE_DMA_QUEUED"); + case 0xcd: return ("CFA_WRITE_MULTIPLE_WITHOUT_ERASE"); + case 0xce: return ("WRITE_MULTIPLE_FUA48"); + case 0xd1: return ("CHECK_MEDIA_CARD_TYPE"); + case 0xda: return ("GET_MEDIA_STATUS"); + case 0xde: return ("MEDIA_LOCK"); + case 0xdf: return ("MEDIA_UNLOCK"); + case 0xe0: return ("STANDBY_IMMEDIATE"); + case 0xe1: return ("IDLE_IMMEDIATE"); + case 0xe2: return ("STANDBY"); + case 0xe3: return ("IDLE"); + case 0xe4: return ("READ_BUFFER/PM"); + case 0xe5: return ("CHECK_POWER_MODE"); + case 0xe6: return ("SLEEP"); + case 0xe7: return ("FLUSHCACHE"); + case 0xe8: return ("WRITE_PM"); + case 0xea: return ("FLUSHCACHE48"); + case 0xec: return ("ATA_IDENTIFY"); + case 0xed: return ("MEDIA_EJECT"); + case 0xef: + switch (cmd->features) { + case 0x03: return ("SETFEATURES SET TRANSFER MODE"); + case 0x02: return ("SETFEATURES ENABLE WCACHE"); + case 0x82: return ("SETFEATURES DISABLE WCACHE"); + case 0xaa: return ("SETFEATURES ENABLE RCACHE"); + case 0x55: return ("SETFEATURES DISABLE RCACHE"); + } + return "SETFEATURES"; + case 0xf1: return ("SECURITY_SET_PASSWORD"); + case 0xf2: return ("SECURITY_UNLOCK"); + case 0xf3: return ("SECURITY_ERASE_PREPARE"); + case 0xf4: return ("SECURITY_ERASE_UNIT"); + case 0xf5: return ("SECURITY_FREE_LOCK"); + case 0xf6: return ("SECURITY DISABLE PASSWORD"); + case 0xf8: return ("READ_NATIVE_MAX_ADDRESS"); + case 0xf9: return ("SET_MAX_ADDRESS"); + } + return "UNKNOWN"; +} + +char * +ata_cmd_string(struct ata_cmd *cmd, char *cmd_string, size_t len) +{ + + snprintf(cmd_string, len, "%02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x", + cmd->command, cmd->features, + cmd->lba_low, cmd->lba_mid, cmd->lba_high, cmd->device, + cmd->lba_low_exp, cmd->lba_mid_exp, cmd->lba_high_exp, + cmd->features_exp, cmd->sector_count, cmd->sector_count_exp); + + return(cmd_string); +} + +char * +ata_res_string(struct ata_res *res, char *res_string, size_t len) +{ + + snprintf(res_string, len, "%02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x", + res->status, res->error, + res->lba_low, res->lba_mid, res->lba_high, res->device, + res->lba_low_exp, res->lba_mid_exp, res->lba_high_exp, + res->sector_count, res->sector_count_exp); + + return(res_string); +} + +/* + * ata_command_sbuf() returns 0 for success and -1 for failure. + */ +int +ata_command_sbuf(struct ccb_ataio *ataio, struct sbuf *sb) +{ + char cmd_str[(12 * 3) + 1]; + + sbuf_printf(sb, "CMD: %s: %s", + ata_op_string(&ataio->cmd), + ata_cmd_string(&ataio->cmd, cmd_str, sizeof(cmd_str))); + + return(0); +} + +/* + * ata_status_abuf() returns 0 for success and -1 for failure. + */ +int +ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb) +{ + + sbuf_printf(sb, "ATA Status: %02x (%s%s%s%s%s%s%s%s)", + ataio->res.status, + (ataio->res.status & 0x80) ? "BSY " : "", + (ataio->res.status & 0x40) ? "DRDY " : "", + (ataio->res.status & 0x20) ? "DF " : "", + (ataio->res.status & 0x10) ? "SERV " : "", + (ataio->res.status & 0x08) ? "DRQ " : "", + (ataio->res.status & 0x04) ? "CORR " : "", + (ataio->res.status & 0x02) ? "IDX " : "", + (ataio->res.status & 0x01) ? "ERR" : ""); + if (ataio->res.status & 1) { + sbuf_printf(sb, ", Error: %02x (%s%s%s%s%s%s%s%s)", + ataio->res.error, + (ataio->res.error & 0x80) ? "ICRC " : "", + (ataio->res.error & 0x40) ? "UNC " : "", + (ataio->res.error & 0x20) ? "MC " : "", + (ataio->res.error & 0x10) ? "IDNF " : "", + (ataio->res.error & 0x08) ? "MCR " : "", + (ataio->res.error & 0x04) ? "ABRT " : "", + (ataio->res.error & 0x02) ? "NM " : "", + (ataio->res.error & 0x01) ? "ILI" : ""); + } + + return(0); +} + +/* + * ata_res_sbuf() returns 0 for success and -1 for failure. + */ +int +ata_res_sbuf(struct ccb_ataio *ataio, struct sbuf *sb) +{ + char res_str[(11 * 3) + 1]; + + sbuf_printf(sb, "RES: %s", + ata_res_string(&ataio->res, res_str, sizeof(res_str))); + + return(0); +} + void ata_print_ident(struct ata_params *ident_data) { Modified: head/sys/cam/ata/ata_all.h ============================================================================== --- head/sys/cam/ata/ata_all.h Tue Nov 3 09:28:45 2009 (r198848) +++ head/sys/cam/ata/ata_all.h Tue Nov 3 11:19:05 2009 (r198849) @@ -81,6 +81,14 @@ struct ata_res { }; int ata_version(int ver); + +char * ata_op_string(struct ata_cmd *cmd); +char * ata_cmd_string(struct ata_cmd *cmd, char *cmd_string, size_t len); +char * ata_res_string(struct ata_res *res, char *res_string, size_t len); +int ata_command_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); +int ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); +int ata_res_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); + void ata_print_ident(struct ata_params *ident_data); void ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, Modified: head/sys/cam/cam.c ============================================================================== --- head/sys/cam/cam.c Tue Nov 3 09:28:45 2009 (r198848) +++ head/sys/cam/cam.c Tue Nov 3 11:19:05 2009 (r198849) @@ -229,6 +229,21 @@ cam_error_string(struct cam_device *devi return(NULL); switch (ccb->ccb_h.func_code) { + case XPT_ATA_IO: + switch (proto_flags & CAM_EPF_LEVEL_MASK) { + case CAM_EPF_NONE: + break; + case CAM_EPF_ALL: + case CAM_EPF_NORMAL: + proto_flags |= CAM_EAF_PRINT_RESULT; + /* FALLTHROUGH */ + case CAM_EPF_MINIMAL: + proto_flags |= CAM_EAF_PRINT_STATUS; + /* FALLTHROUGH */ + default: + break; + } + break; case XPT_SCSI_IO: switch (proto_flags & CAM_EPF_LEVEL_MASK) { case CAM_EPF_NONE: @@ -256,10 +271,12 @@ cam_error_string(struct cam_device *devi sbuf_new(&sb, str, str_len, 0); if (flags & CAM_ESF_COMMAND) { - sbuf_cat(&sb, path_str); - switch (ccb->ccb_h.func_code) { + case XPT_ATA_IO: + ata_command_sbuf(&ccb->ataio, &sb); + sbuf_printf(&sb, "\n"); + break; case XPT_SCSI_IO: #ifdef _KERNEL scsi_command_string(&ccb->csio, &sb); @@ -267,7 +284,6 @@ cam_error_string(struct cam_device *devi scsi_command_string(device, &ccb->csio, &sb); #endif /* _KERNEL/!_KERNEL */ sbuf_printf(&sb, "\n"); - break; default: break; @@ -295,6 +311,22 @@ cam_error_string(struct cam_device *devi if (flags & CAM_ESF_PROTO_STATUS) { switch (ccb->ccb_h.func_code) { + case XPT_ATA_IO: + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != + CAM_ATA_STATUS_ERROR) + break; + if (proto_flags & CAM_EAF_PRINT_STATUS) { + sbuf_cat(&sb, path_str); + ata_status_sbuf(&ccb->ataio, &sb); + sbuf_printf(&sb, "\n"); + } + if (proto_flags & CAM_EAF_PRINT_RESULT) { + sbuf_cat(&sb, path_str); + ata_res_sbuf(&ccb->ataio, &sb); + sbuf_printf(&sb, "\n"); + } + + break; case XPT_SCSI_IO: if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR) @@ -302,10 +334,6 @@ cam_error_string(struct cam_device *devi if (proto_flags & CAM_ESF_PRINT_STATUS) { sbuf_cat(&sb, path_str); - /* - * Print out the SCSI status byte as long as - * the user wants some protocol output. - */ sbuf_printf(&sb, "SCSI Status: %s\n", scsi_status_string(&ccb->csio)); } Modified: head/sys/cam/cam.h ============================================================================== --- head/sys/cam/cam.h Tue Nov 3 09:28:45 2009 (r198848) +++ head/sys/cam/cam.h Tue Nov 3 11:19:05 2009 (r198849) @@ -184,6 +184,12 @@ typedef enum { CAM_ESF_PRINT_SENSE = 0x20 } cam_error_scsi_flags; +typedef enum { + CAM_EAF_PRINT_NONE = 0x00, + CAM_EAF_PRINT_STATUS = 0x10, + CAM_EAF_PRINT_RESULT = 0x20 +} cam_error_ata_flags; + struct cam_status_entry { cam_status status_code; Modified: head/sys/cam/cam_periph.c ============================================================================== --- head/sys/cam/cam_periph.c Tue Nov 3 09:28:45 2009 (r198848) +++ head/sys/cam/cam_periph.c Tue Nov 3 11:19:05 2009 (r198849) @@ -1612,6 +1612,7 @@ cam_periph_error(union ccb *ccb, cam_fla if (bootverbose && printed == 0) { xpt_print(ccb->ccb_h.path, "Request completed with CAM_ATA_STATUS_ERROR\n"); + cam_error_print(ccb, CAM_ESF_ALL, CAM_EPF_ALL); printed++; } /* FALLTHROUGH */