Commit 277c7105 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://gkernel.bkbits.net/libata-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents fadf035a 043ea303
......@@ -818,7 +818,7 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
* @dev: Device whose IDENTIFY DEVICE results we will examine
* @s: string into which data is output
* @ofs: offset into identify device page
* @len: length of string to return
* @len: length of string to return. must be an even number.
*
* The strings in the IDENTIFY DEVICE page are broken up into
* 16-bit chunks. Run through the string, and output each
......@@ -847,29 +847,6 @@ void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
}
}
/**
* ata_dev_parse_strings - Store useful IDENTIFY DEVICE page strings
* @dev: Device whose IDENTIFY DEVICE page info we use
*
* We store 'vendor' and 'product' strings read from the device,
* for later use in the SCSI simulator's INQUIRY data.
*
* Set these strings here, in the case of 'product', using
* data read from the ATA IDENTIFY DEVICE page.
*
* LOCKING:
* caller.
*/
static void ata_dev_parse_strings(struct ata_device *dev)
{
assert (dev->class == ATA_DEV_ATA);
memcpy(dev->vendor, "ATA ", 8);
ata_dev_id_string(dev, dev->product, ATA_ID_PROD_OFS,
sizeof(dev->product));
}
/**
* __ata_dev_select - Select device 0/1 on ATA bus
* @ap: ATA channel to manipulate
......@@ -1127,8 +1104,6 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
ata_dump_id(dev);
ata_dev_parse_strings(dev);
/* ATA-specific feature tests */
if (dev->class == ATA_DEV_ATA) {
if (!ata_id_is_ata(dev)) /* sanity check */
......@@ -2346,7 +2321,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
if (cmd) {
if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
if (qc->flags & ATA_QCFLAG_ATAPI)
if (is_atapi_taskfile(&qc->tf))
cmd->result = SAM_STAT_CHECK_CONDITION;
else
ata_to_sense_error(qc);
......@@ -2659,6 +2634,8 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
unsigned int handled = 0;
switch (qc->tf.protocol) {
/* BMDMA completion */
case ATA_PROT_DMA:
case ATA_PROT_ATAPI_DMA:
if (ap->flags & ATA_FLAG_MMIO) {
......@@ -2677,8 +2654,16 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
handled = 1;
break;
/* command completion, but no data xfer */
/* FIXME: a shared interrupt _will_ cause a non-data command
* to be completed prematurely, with an error.
*
* This doesn't matter right now, since we aren't sending
* non-data commands down this pipe except in development
* situations.
*/
case ATA_PROT_ATAPI:
case ATA_PROT_NODATA: /* command completion, but no data xfer */
case ATA_PROT_NODATA:
status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
ata_qc_complete(qc, status);
......@@ -3525,3 +3510,4 @@ EXPORT_SYMBOL_GPL(ata_scsi_error);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
EXPORT_SYMBOL_GPL(ata_scsi_release);
EXPORT_SYMBOL_GPL(ata_host_intr);
EXPORT_SYMBOL_GPL(ata_dev_id_string);
......@@ -498,7 +498,9 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen)
{
const u8 hdr[] = {
struct ata_device *dev = args->dev;
u8 hdr[] = {
TYPE_DISK,
0,
0x5, /* claim SPC-3 version compatibility */
......@@ -506,14 +508,20 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
96 - 4
};
/* set scsi removeable (RMB) bit per ata bit */
if (ata_id_removeable(dev))
hdr[1] |= (1 << 7);
VPRINTK("ENTER\n");
memcpy(rbuf, hdr, sizeof(hdr));
if (buflen > 36) {
memcpy(&rbuf[8], args->dev->vendor, 8);
memcpy(&rbuf[16], args->dev->product, 16);
memcpy(&rbuf[32], DRV_VERSION, 4);
memcpy(&rbuf[8], "ATA ", 8);
ata_dev_id_string(dev, &rbuf[16], ATA_ID_PROD_OFS, 16);
ata_dev_id_string(dev, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
if (rbuf[32] == 0 || rbuf[32] == ' ')
memcpy(&rbuf[32], "n/a ", 4);
}
if (buflen > 63) {
......@@ -687,9 +695,17 @@ static void ata_msense_push(u8 **ptr_io, const u8 *last,
static unsigned int ata_msense_caching(struct ata_device *dev, u8 **ptr_io,
const u8 *last)
{
u8 page[7] = { 0xf, 0, 0x10, 0, 0x8, 0xa, 0 };
if (dev->flags & ATA_DFLAG_WCACHE)
page[6] = 0x4;
u8 page[] = {
0x8, /* page code */
0x12, /* page length */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 zeroes */
0, 0, 0, 0, 0, 0, 0, 0 /* 8 zeroes */
};
if (ata_id_wcache_enabled(dev))
page[2] |= (1 << 2); /* write cache enable */
if (!ata_id_rahead_enabled(dev))
page[12] |= (1 << 5); /* disable read ahead */
ata_msense_push(ptr_io, last, page, sizeof(page));
return sizeof(page);
......@@ -715,6 +731,31 @@ static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last)
return sizeof(page);
}
/**
* ata_msense_rw_recovery - Simulate MODE SENSE r/w error recovery page
* @dev: Device associated with this MODE SENSE command
* @ptr_io: (input/output) Location to store more output data
* @last: End of output data buffer
*
* Generate a generic MODE SENSE r/w error recovery page.
*
* LOCKING:
* None.
*/
static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
{
const u8 page[] = {
0x1, /* page code */
0xa, /* page length */
(1 << 7) | (1 << 6), /* note auto r/w reallocation */
0, 0, 0, 0, 0, 0, 0, 0, 0 /* 9 zeroes */
};
ata_msense_push(ptr_io, last, page, sizeof(page));
return sizeof(page);
}
/**
* ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands
* @args: Port / device / SCSI command of interest.
......@@ -754,6 +795,10 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
last = rbuf + buflen - 1;
switch(scsicmd[2] & 0x3f) {
case 0x01: /* r/w error recovery */
output_len += ata_msense_rw_recovery(&p, last);
break;
case 0x08: /* caching */
output_len += ata_msense_caching(dev, &p, last);
break;
......@@ -764,6 +809,7 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
}
case 0x3f: /* all pages */
output_len += ata_msense_rw_recovery(&p, last);
output_len += ata_msense_caching(dev, &p, last);
output_len += ata_msense_ctl_mode(&p, last);
break;
......@@ -804,20 +850,23 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
VPRINTK("ENTER\n");
n_sectors--; /* one off */
n_sectors--; /* ATA TotalUserSectors - 1 */
tmp = n_sectors; /* note: truncates, if lba48 */
if (args->cmd->cmnd[0] == READ_CAPACITY) {
/* sector count, 32-bit */
rbuf[0] = tmp >> (8 * 3);
rbuf[1] = tmp >> (8 * 2);
rbuf[2] = tmp >> (8 * 1);
rbuf[3] = tmp;
/* sector size */
tmp = ATA_SECT_SIZE;
rbuf[6] = tmp >> 8;
rbuf[7] = tmp;
} else {
/* sector count, 64-bit */
rbuf[2] = n_sectors >> (8 * 7);
rbuf[3] = n_sectors >> (8 * 6);
rbuf[4] = n_sectors >> (8 * 5);
......@@ -827,6 +876,7 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
rbuf[8] = tmp >> (8 * 1);
rbuf[9] = tmp;
/* sector size */
tmp = ATA_SECT_SIZE;
rbuf[12] = tmp >> 8;
rbuf[13] = tmp;
......@@ -901,8 +951,6 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
{
struct scsi_cmnd *cmd = qc->scsicmd;
qc->flags |= ATA_QCFLAG_ATAPI;
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
if (cmd->sc_data_direction == SCSI_DATA_WRITE) {
qc->tf.flags |= ATA_TFLAG_WRITE;
......@@ -1106,7 +1154,11 @@ static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
args.done = done;
switch(scsicmd[0]) {
case TEST_UNIT_READY: /* FIXME: correct? */
/* no-op's, complete with success */
case REZERO_UNIT:
case SEEK_6:
case SEEK_10:
case TEST_UNIT_READY:
case FORMAT_UNIT: /* FIXME: correct? */
case SEND_DIAGNOSTIC: /* FIXME: correct? */
ata_scsi_rbuf_fill(&args, ata_scsiop_noop);
......
......@@ -36,8 +36,6 @@ struct ata_scsi_args {
};
/* libata-core.c */
extern void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
unsigned int ofs, unsigned int len);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
struct ata_device *dev);
extern int ata_qc_issue(struct ata_queued_cmd *qc);
......
......@@ -276,8 +276,14 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
{
unsigned int n, quirks = 0;
const char *s = &dev->product[0];
unsigned int len = strnlen(s, sizeof(dev->product));
unsigned char model_num[40];
const char *s;
unsigned int len;
ata_dev_id_string(dev, model_num, ATA_ID_PROD_OFS,
sizeof(model_num));
s = &model_num[0];
len = strnlen(s, sizeof(model_num));
/* ATAPI specifies that empty space is blank-filled; remove blanks */
while ((len > 0) && (s[len - 1] == ' '))
......
......@@ -38,6 +38,7 @@ enum {
ATA_ID_WORDS = 256,
ATA_ID_PROD_OFS = 27,
ATA_ID_FW_REV_OFS = 23,
ATA_ID_SERNO_OFS = 10,
ATA_ID_MAJOR_VER = 80,
ATA_ID_PIO_MODES = 64,
......@@ -103,6 +104,7 @@ enum {
ATA_REG_IRQ = ATA_REG_NSECT,
/* ATA device commands */
ATA_CMD_CHK_POWER = 0xE5, /* check power mode */
ATA_CMD_EDD = 0x90, /* execute device diagnostic */
ATA_CMD_FLUSH = 0xE7,
ATA_CMD_FLUSH_EXT = 0xEA,
......@@ -200,11 +202,14 @@ struct ata_taskfile {
};
#define ata_id_is_ata(dev) (((dev)->id[0] & (1 << 15)) == 0)
#define ata_id_rahead_enabled(dev) ((dev)->id[85] & (1 << 6))
#define ata_id_wcache_enabled(dev) ((dev)->id[85] & (1 << 5))
#define ata_id_has_lba48(dev) ((dev)->id[83] & (1 << 10))
#define ata_id_has_wcache(dev) ((dev)->id[82] & (1 << 5))
#define ata_id_has_pm(dev) ((dev)->id[82] & (1 << 3))
#define ata_id_has_lba(dev) ((dev)->id[49] & (1 << 8))
#define ata_id_has_dma(dev) ((dev)->id[49] & (1 << 9))
#define ata_id_removeable(dev) ((dev)->id[0] & (1 << 7))
#define ata_id_u32(dev,n) \
(((u32) (dev)->id[(n) + 1] << 16) | ((u32) (dev)->id[(n)]))
#define ata_id_u64(dev,n) \
......@@ -213,4 +218,10 @@ struct ata_taskfile {
((u64) dev->id[(n) + 1] << 16) | \
((u64) dev->id[(n) + 0]) )
static inline int is_atapi_taskfile(struct ata_taskfile *tf)
{
return (tf->protocol == ATA_PROT_ATAPI) ||
(tf->protocol == ATA_PROT_ATAPI_DMA);
}
#endif /* __LINUX_ATA_H__ */
......@@ -111,7 +111,6 @@ enum {
ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */
ATA_QCFLAG_DMA = (1 << 2), /* data delivered via DMA */
ATA_QCFLAG_ATAPI = (1 << 3), /* is ATAPI packet command? */
ATA_QCFLAG_SG = (1 << 4), /* have s/g table? */
/* various lengths of time */
......@@ -260,12 +259,6 @@ struct ata_device {
unsigned int pio_mode;
unsigned int udma_mode;
unsigned char vendor[8]; /* space-padded, not ASCIIZ */
unsigned char product[32]; /* WARNING: shorter than
* ATAPI7 spec size, 40 ASCII
* characters
*/
/* cache info about current transfer mode */
u8 xfer_protocol; /* taskfile xfer protocol */
u8 read_cmd; /* opcode to use on read */
......@@ -398,6 +391,8 @@ extern int ata_port_start (struct ata_port *ap);
extern void ata_port_stop (struct ata_port *ap);
extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
extern void ata_fill_sg(struct ata_queued_cmd *qc);
extern void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
unsigned int ofs, unsigned int len);
extern void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc);
extern void ata_bmdma_start_mmio (struct ata_queued_cmd *qc);
extern void ata_bmdma_setup_pio (struct ata_queued_cmd *qc);
......
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