diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-03-24 09:24:04 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-24 09:24:04 -0500 |
commit | 11ed56fb7899f9eb9eaef8e5919db1bf08f1b07e (patch) | |
tree | b01421cb139b11065d776ed361a7a12b3a1aecc9 /drivers/scsi/sata_vsc.c | |
parent | 54da9a3968448681d0ddf193ec90f2480c5cba1c (diff) | |
parent | 2cc432eed0491df66e14b578139bba2c75fb3f9a (diff) |
Merge branch 'upstream'
Conflicts:
drivers/scsi/sata_vsc.c
Diffstat (limited to 'drivers/scsi/sata_vsc.c')
-rw-r--r-- | drivers/scsi/sata_vsc.c | 120 |
1 files changed, 70 insertions, 50 deletions
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 5845758e9a69..8c818d47c1fd 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c | |||
@@ -47,52 +47,58 @@ | |||
47 | #include <linux/libata.h> | 47 | #include <linux/libata.h> |
48 | 48 | ||
49 | #define DRV_NAME "sata_vsc" | 49 | #define DRV_NAME "sata_vsc" |
50 | #define DRV_VERSION "1.1" | 50 | #define DRV_VERSION "1.2" |
51 | 51 | ||
52 | /* Interrupt register offsets (from chip base address) */ | 52 | enum { |
53 | #define VSC_SATA_INT_STAT_OFFSET 0x00 | 53 | /* Interrupt register offsets (from chip base address) */ |
54 | #define VSC_SATA_INT_MASK_OFFSET 0x04 | 54 | VSC_SATA_INT_STAT_OFFSET = 0x00, |
55 | 55 | VSC_SATA_INT_MASK_OFFSET = 0x04, | |
56 | /* Taskfile registers offsets */ | 56 | |
57 | #define VSC_SATA_TF_CMD_OFFSET 0x00 | 57 | /* Taskfile registers offsets */ |
58 | #define VSC_SATA_TF_DATA_OFFSET 0x00 | 58 | VSC_SATA_TF_CMD_OFFSET = 0x00, |
59 | #define VSC_SATA_TF_ERROR_OFFSET 0x04 | 59 | VSC_SATA_TF_DATA_OFFSET = 0x00, |
60 | #define VSC_SATA_TF_FEATURE_OFFSET 0x06 | 60 | VSC_SATA_TF_ERROR_OFFSET = 0x04, |
61 | #define VSC_SATA_TF_NSECT_OFFSET 0x08 | 61 | VSC_SATA_TF_FEATURE_OFFSET = 0x06, |
62 | #define VSC_SATA_TF_LBAL_OFFSET 0x0c | 62 | VSC_SATA_TF_NSECT_OFFSET = 0x08, |
63 | #define VSC_SATA_TF_LBAM_OFFSET 0x10 | 63 | VSC_SATA_TF_LBAL_OFFSET = 0x0c, |
64 | #define VSC_SATA_TF_LBAH_OFFSET 0x14 | 64 | VSC_SATA_TF_LBAM_OFFSET = 0x10, |
65 | #define VSC_SATA_TF_DEVICE_OFFSET 0x18 | 65 | VSC_SATA_TF_LBAH_OFFSET = 0x14, |
66 | #define VSC_SATA_TF_STATUS_OFFSET 0x1c | 66 | VSC_SATA_TF_DEVICE_OFFSET = 0x18, |
67 | #define VSC_SATA_TF_COMMAND_OFFSET 0x1d | 67 | VSC_SATA_TF_STATUS_OFFSET = 0x1c, |
68 | #define VSC_SATA_TF_ALTSTATUS_OFFSET 0x28 | 68 | VSC_SATA_TF_COMMAND_OFFSET = 0x1d, |
69 | #define VSC_SATA_TF_CTL_OFFSET 0x29 | 69 | VSC_SATA_TF_ALTSTATUS_OFFSET = 0x28, |
70 | 70 | VSC_SATA_TF_CTL_OFFSET = 0x29, | |
71 | /* DMA base */ | 71 | |
72 | #define VSC_SATA_UP_DESCRIPTOR_OFFSET 0x64 | 72 | /* DMA base */ |
73 | #define VSC_SATA_UP_DATA_BUFFER_OFFSET 0x6C | 73 | VSC_SATA_UP_DESCRIPTOR_OFFSET = 0x64, |
74 | #define VSC_SATA_DMA_CMD_OFFSET 0x70 | 74 | VSC_SATA_UP_DATA_BUFFER_OFFSET = 0x6C, |
75 | 75 | VSC_SATA_DMA_CMD_OFFSET = 0x70, | |
76 | /* SCRs base */ | 76 | |
77 | #define VSC_SATA_SCR_STATUS_OFFSET 0x100 | 77 | /* SCRs base */ |
78 | #define VSC_SATA_SCR_ERROR_OFFSET 0x104 | 78 | VSC_SATA_SCR_STATUS_OFFSET = 0x100, |
79 | #define VSC_SATA_SCR_CONTROL_OFFSET 0x108 | 79 | VSC_SATA_SCR_ERROR_OFFSET = 0x104, |
80 | 80 | VSC_SATA_SCR_CONTROL_OFFSET = 0x108, | |
81 | /* Port stride */ | 81 | |
82 | #define VSC_SATA_PORT_OFFSET 0x200 | 82 | /* Port stride */ |
83 | 83 | VSC_SATA_PORT_OFFSET = 0x200, | |
84 | /* Error interrupt status bit offsets */ | 84 | |
85 | #define VSC_SATA_INT_ERROR_E_OFFSET 2 | 85 | /* Error interrupt status bit offsets */ |
86 | #define VSC_SATA_INT_ERROR_P_OFFSET 4 | 86 | VSC_SATA_INT_ERROR_CRC = 0x40, |
87 | #define VSC_SATA_INT_ERROR_T_OFFSET 5 | 87 | VSC_SATA_INT_ERROR_T = 0x20, |
88 | #define VSC_SATA_INT_ERROR_M_OFFSET 1 | 88 | VSC_SATA_INT_ERROR_P = 0x10, |
89 | VSC_SATA_INT_ERROR_R = 0x8, | ||
90 | VSC_SATA_INT_ERROR_E = 0x4, | ||
91 | VSC_SATA_INT_ERROR_M = 0x2, | ||
92 | VSC_SATA_INT_PHY_CHANGE = 0x1, | ||
93 | VSC_SATA_INT_ERROR = (VSC_SATA_INT_ERROR_CRC | VSC_SATA_INT_ERROR_T | \ | ||
94 | VSC_SATA_INT_ERROR_P | VSC_SATA_INT_ERROR_R | \ | ||
95 | VSC_SATA_INT_ERROR_E | VSC_SATA_INT_ERROR_M | \ | ||
96 | VSC_SATA_INT_PHY_CHANGE), | ||
97 | }; | ||
98 | |||
99 | |||
89 | #define is_vsc_sata_int_err(port_idx, int_status) \ | 100 | #define is_vsc_sata_int_err(port_idx, int_status) \ |
90 | (int_status & ((1 << (VSC_SATA_INT_ERROR_E_OFFSET + (8 * port_idx))) | \ | 101 | (int_status & (VSC_SATA_INT_ERROR << (8 * port_idx))) |
91 | (1 << (VSC_SATA_INT_ERROR_P_OFFSET + (8 * port_idx))) | \ | ||
92 | (1 << (VSC_SATA_INT_ERROR_T_OFFSET + (8 * port_idx))) | \ | ||
93 | (1 << (VSC_SATA_INT_ERROR_M_OFFSET + (8 * port_idx))) \ | ||
94 | )\ | ||
95 | ) | ||
96 | 102 | ||
97 | 103 | ||
98 | static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | 104 | static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) |
@@ -223,18 +229,33 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, | |||
223 | handled++; | 229 | handled++; |
224 | } | 230 | } |
225 | 231 | ||
226 | if (ap && !(ap->flags & ATA_FLAG_PORT_DISABLED)) { | 232 | if (ap && !(ap->flags & |
233 | (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { | ||
227 | struct ata_queued_cmd *qc; | 234 | struct ata_queued_cmd *qc; |
228 | 235 | ||
229 | qc = ata_qc_from_tag(ap, ap->active_tag); | 236 | qc = ata_qc_from_tag(ap, ap->active_tag); |
230 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) | 237 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) |
231 | handled += ata_host_intr(ap, qc); | 238 | handled += ata_host_intr(ap, qc); |
232 | else { | 239 | } else if (is_vsc_sata_int_err(i, int_status)) { |
233 | printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); | 240 | /* |
241 | * On some chips (i.e. Intel 31244), an error | ||
242 | * interrupt will sneak in at initialization | ||
243 | * time (phy state changes). Clearing the SCR | ||
244 | * error register is not required, but it prevents | ||
245 | * the phy state change interrupts from recurring | ||
246 | * later. | ||
247 | */ | ||
248 | u32 err_status; | ||
249 | err_status = vsc_sata_scr_read(ap, SCR_ERROR); | ||
250 | printk(KERN_DEBUG "%s: clearing interrupt, " | ||
251 | "status %x; sata err status %x\n", | ||
252 | __FUNCTION__, | ||
253 | int_status, err_status); | ||
254 | vsc_sata_scr_write(ap, SCR_ERROR, err_status); | ||
255 | /* Clear interrupt status */ | ||
234 | ata_chk_status(ap); | 256 | ata_chk_status(ap); |
235 | handled++; | 257 | handled++; |
236 | } | 258 | } |
237 | |||
238 | } | 259 | } |
239 | } | 260 | } |
240 | } | 261 | } |
@@ -250,7 +271,6 @@ static struct scsi_host_template vsc_sata_sht = { | |||
250 | .name = DRV_NAME, | 271 | .name = DRV_NAME, |
251 | .ioctl = ata_scsi_ioctl, | 272 | .ioctl = ata_scsi_ioctl, |
252 | .queuecommand = ata_scsi_queuecmd, | 273 | .queuecommand = ata_scsi_queuecmd, |
253 | .eh_timed_out = ata_scsi_timed_out, | ||
254 | .eh_strategy_handler = ata_scsi_error, | 274 | .eh_strategy_handler = ata_scsi_error, |
255 | .can_queue = ATA_DEF_QUEUE, | 275 | .can_queue = ATA_DEF_QUEUE, |
256 | .this_id = ATA_SHT_THIS_ID, | 276 | .this_id = ATA_SHT_THIS_ID, |