static inline error_cause decode_irq_cause(fdc_mode_enum mode, __u8 st[]) { error_cause cause = no_error; TRACE_FUN(ft_t_any); /* Valid st[], decode cause of interrupt. */ switch (st[0] & ST0_INT_MASK) { case FDC_INT_NORMAL: TRACE(ft_t_fdc_dma,"normal completion: %s",fdc_mode_txt(mode)); break; case FDC_INT_ABNORMAL: TRACE(ft_t_flow, "abnormal completion %s", fdc_mode_txt(mode)); TRACE(ft_t_fdc_dma, "ST0: 0x%02x, ST1: 0x%02x, ST2: 0x%02x", st[0], st[1], st[2]); TRACE(ft_t_fdc_dma, "C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x", st[3], st[4], st[5], st[6]); if (st[1] & 0x01) { if (st[2] & 0x01) { cause = data_am_error; } else { cause = id_am_error; } } else if (st[1] & 0x20) { if (st[2] & 0x20) { cause = data_crc_error; } else { cause = id_crc_error; } } else if (st[1] & 0x04) { cause = no_data_error; } else if (st[1] & 0x10) { cause = overrun_error; } print_error_cause(cause); break; case FDC_INT_INVALID: TRACE(ft_t_flow, "invalid completion %s", fdc_mode_txt(mode)); break; case FDC_INT_READYCH: if (st[0] & ST0_SEEK_END) { TRACE(ft_t_flow, "drive poll completed"); } else { TRACE(ft_t_flow, "ready change %s",fdc_mode_txt(mode)); } break; default: break; } TRACE_EXIT cause; }
static void print_error_cause(int cause) { TRACE_FUN(ft_t_any); switch (cause) { case no_data_error: TRACE(ft_t_noise, "no data error"); break; case id_am_error: TRACE(ft_t_noise, "id am error"); break; case id_crc_error: TRACE(ft_t_noise, "id crc error"); break; case data_am_error: TRACE(ft_t_noise, "data am error"); break; case data_crc_error: TRACE(ft_t_noise, "data crc error"); break; case overrun_error: TRACE(ft_t_noise, "overrun error"); break; default: } TRACE_EXIT; } static char *fdc_mode_txt(fdc_mode_enum mode) { switch (mode) { case fdc_idle: return "fdc_idle"; case fdc_reading_data: return "fdc_reading_data"; case fdc_seeking: return "fdc_seeking"; case fdc_writing_data: return "fdc_writing_data"; case fdc_reading_id: return "fdc_reading_id"; case fdc_recalibrating: return "fdc_recalibrating"; case fdc_formatting: return "fdc_formatting"; case fdc_verifying: return "fdc_verifying"; default: return "unknown"; } } static inline error_cause decode_irq_cause(fdc_mode_enum mode, __u8 st[]) { error_cause cause = no_error; TRACE_FUN(ft_t_any); /* Valid st[], decode cause of interrupt. */ switch (st[0] & ST0_INT_MASK) { case FDC_INT_NORMAL: TRACE(ft_t_fdc_dma,"normal completion: %s",fdc_mode_txt(mode)); break; case FDC_INT_ABNORMAL: TRACE(ft_t_flow, "abnormal completion %s", fdc_mode_txt(mode)); TRACE(ft_t_fdc_dma, "ST0: 0x%02x, ST1: 0x%02x, ST2: 0x%02x", st[0], st[1], st[2]); TRACE(ft_t_fdc_dma, "C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x", st[3], st[4], st[5], st[6]); if (st[1] & 0x01) { if (st[2] & 0x01) { cause = data_am_error; } else { cause = id_am_error; } } else if (st[1] & 0x20) { if (st[2] & 0x20) { cause = data_crc_error; } else { cause = id_crc_error; } } else if (st[1] & 0x04) { cause = no_data_error; } else if (st[1] & 0x10) { cause = overrun_error; } print_error_cause(cause); break; case FDC_INT_INVALID: TRACE(ft_t_flow, "invalid completion %s", fdc_mode_txt(mode)); break; case FDC_INT_READYCH: if (st[0] & ST0_SEEK_END) { TRACE(ft_t_flow, "drive poll completed"); } else { TRACE(ft_t_flow, "ready change %s",fdc_mode_txt(mode)); } break; default: break; } TRACE_EXIT cause; }