Commit 963e4975 authored by Alan Cox's avatar Alan Cox Committed by Jeff Garzik

pata_it821x: Driver updates and reworking

- Add support for the RDC 1010 variant
- Rework the core library to have a read_id method. This allows the hacky
  bits of it821x to go and prepares us for pata_hd
- Switch from WARN to BUG in ata_id_string as it will reboot if you get
  it wrong so WARN won't be seen
- Allow the issue of command 0xFC on the 821x. This is needed to query
  rebuild status.
- Tidy up printk formatting
- Do more ident rewriting on RAID volumes to handle firmware provided
  ident data which is rather wonky
- Report the firmware revision and device layout in RAID mode
- Don't try and disable raid on the 8211 or RDC - they don't have the
  relevant bits
Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 1f938d06
...@@ -1132,6 +1132,8 @@ void ata_id_string(const u16 *id, unsigned char *s, ...@@ -1132,6 +1132,8 @@ void ata_id_string(const u16 *id, unsigned char *s,
{ {
unsigned int c; unsigned int c;
BUG_ON(len & 1);
while (len > 0) { while (len > 0) {
c = id[ofs] >> 8; c = id[ofs] >> 8;
*s = c; *s = c;
...@@ -1165,8 +1167,6 @@ void ata_id_c_string(const u16 *id, unsigned char *s, ...@@ -1165,8 +1167,6 @@ void ata_id_c_string(const u16 *id, unsigned char *s,
{ {
unsigned char *p; unsigned char *p;
WARN_ON(!(len & 1));
ata_id_string(id, s, ofs, len - 1); ata_id_string(id, s, ofs, len - 1);
p = s + strnlen(s, len - 1); p = s + strnlen(s, len - 1);
...@@ -1885,6 +1885,23 @@ static u32 ata_pio_mask_no_iordy(const struct ata_device *adev) ...@@ -1885,6 +1885,23 @@ static u32 ata_pio_mask_no_iordy(const struct ata_device *adev)
return 3 << ATA_SHIFT_PIO; return 3 << ATA_SHIFT_PIO;
} }
/**
* ata_do_dev_read_id - default ID read method
* @dev: device
* @tf: proposed taskfile
* @id: data buffer
*
* Issue the identify taskfile and hand back the buffer containing
* identify data. For some RAID controllers and for pre ATA devices
* this function is wrapped or replaced by the driver
*/
unsigned int ata_do_dev_read_id(struct ata_device *dev,
struct ata_taskfile *tf, u16 *id)
{
return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE,
id, sizeof(id[0]) * ATA_ID_WORDS, 0);
}
/** /**
* ata_dev_read_id - Read ID data from the specified device * ata_dev_read_id - Read ID data from the specified device
* @dev: target device * @dev: target device
...@@ -1920,7 +1937,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, ...@@ -1920,7 +1937,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
if (ata_msg_ctl(ap)) if (ata_msg_ctl(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __func__); ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __func__);
retry: retry:
ata_tf_init(dev, &tf); ata_tf_init(dev, &tf);
switch (class) { switch (class) {
...@@ -1948,8 +1965,11 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, ...@@ -1948,8 +1965,11 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
*/ */
tf.flags |= ATA_TFLAG_POLLING; tf.flags |= ATA_TFLAG_POLLING;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, if (ap->ops->read_id)
id, sizeof(id[0]) * ATA_ID_WORDS, 0); err_mask = ap->ops->read_id(dev, &tf, id);
else
err_mask = ata_do_dev_read_id(dev, &tf, id);
if (err_mask) { if (err_mask) {
if (err_mask & AC_ERR_NODEV_HINT) { if (err_mask & AC_ERR_NODEV_HINT) {
ata_dev_printk(dev, KERN_DEBUG, ata_dev_printk(dev, KERN_DEBUG,
...@@ -6283,6 +6303,7 @@ EXPORT_SYMBOL_GPL(ata_host_resume); ...@@ -6283,6 +6303,7 @@ EXPORT_SYMBOL_GPL(ata_host_resume);
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
EXPORT_SYMBOL_GPL(ata_id_string); EXPORT_SYMBOL_GPL(ata_id_string);
EXPORT_SYMBOL_GPL(ata_id_c_string); EXPORT_SYMBOL_GPL(ata_id_c_string);
EXPORT_SYMBOL_GPL(ata_do_dev_read_id);
EXPORT_SYMBOL_GPL(ata_scsi_simulate); EXPORT_SYMBOL_GPL(ata_scsi_simulate);
EXPORT_SYMBOL_GPL(ata_pio_need_iordy); EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
......
This diff is collapsed.
...@@ -750,6 +750,7 @@ struct ata_port_operations { ...@@ -750,6 +750,7 @@ struct ata_port_operations {
void (*set_piomode)(struct ata_port *ap, struct ata_device *dev); void (*set_piomode)(struct ata_port *ap, struct ata_device *dev);
void (*set_dmamode)(struct ata_port *ap, struct ata_device *dev); void (*set_dmamode)(struct ata_port *ap, struct ata_device *dev);
int (*set_mode)(struct ata_link *link, struct ata_device **r_failed_dev); int (*set_mode)(struct ata_link *link, struct ata_device **r_failed_dev);
unsigned int (*read_id)(struct ata_device *dev, struct ata_taskfile *tf, u16 *id);
void (*dev_config)(struct ata_device *dev); void (*dev_config)(struct ata_device *dev);
...@@ -951,6 +952,8 @@ extern void ata_id_string(const u16 *id, unsigned char *s, ...@@ -951,6 +952,8 @@ extern void ata_id_string(const u16 *id, unsigned char *s,
unsigned int ofs, unsigned int len); unsigned int ofs, unsigned int len);
extern void ata_id_c_string(const u16 *id, unsigned char *s, extern void ata_id_c_string(const u16 *id, unsigned char *s,
unsigned int ofs, unsigned int len); unsigned int ofs, unsigned int len);
extern unsigned int ata_do_dev_read_id(struct ata_device *dev,
struct ata_taskfile *tf, u16 *id);
extern void ata_qc_complete(struct ata_queued_cmd *qc); extern void ata_qc_complete(struct ata_queued_cmd *qc);
extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active); extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active);
extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment