Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 22418
b: refs/heads/master
c: 949ec2c
h: refs/heads/master
v: v3
  • Loading branch information
Jeff Garzik committed Mar 22, 2006
1 parent cafc7fa commit 09d86f5
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 153 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e952f31bce6e9f64db01f607abc46529ba57ac9e
refs/heads/master: 949ec2c8e6b7b89179b85baf6309c009e1a1b951
4 changes: 2 additions & 2 deletions trunk/drivers/scsi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -595,10 +595,10 @@ config SCSI_SATA_VIA
If unsure, say N.

config SCSI_SATA_VITESSE
tristate "VITESSE VSC-7174 SATA support"
tristate "VITESSE VSC-7174 / INTEL 31244 SATA support"
depends on SCSI_SATA && PCI
help
This option enables support for Vitesse VSC7174 Serial ATA.
This option enables support for Vitesse VSC7174 and Intel 31244 Serial ATA.

If unsure, say N.

Expand Down
37 changes: 37 additions & 0 deletions trunk/drivers/scsi/libata-bmdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
goto err_out_regions;
}

/* FIXME: If we get no DMA mask we should fall back to PIO */
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
goto err_out_regions;
Expand Down Expand Up @@ -699,5 +700,41 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
return rc;
}

/**
* ata_pci_clear_simplex - attempt to kick device out of simplex
* @pdev: PCI device
*
* Some PCI ATA devices report simplex mode but in fact can be told to
* enter non simplex mode. This implements the neccessary logic to
* perform the task on such devices. Calling it on other devices will
* have -undefined- behaviour.
*/

int ata_pci_clear_simplex(struct pci_dev *pdev)
{
unsigned long bmdma = pci_resource_start(pdev, 4);
u8 simplex;

if (bmdma == 0)
return -ENOENT;

simplex = inb(bmdma + 0x02);
outb(simplex & 0x60, bmdma + 0x02);
simplex = inb(bmdma + 0x02);
if (simplex & 0x80)
return -EOPNOTSUPP;
return 0;
}

unsigned long ata_pci_default_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long xfer_mask)
{
/* Filter out DMA modes if the device has been configured by
the BIOS as PIO only */

if (ap->ioaddr.bmdma_addr == 0)
xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
return xfer_mask;
}

#endif /* CONFIG_PCI */

27 changes: 17 additions & 10 deletions trunk/drivers/scsi/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,8 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
spin_unlock_irqrestore(&ap->host_set->lock, flags);

if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) {
ata_port_flush_task(ap);

spin_lock_irqsave(&ap->host_set->lock, flags);

/* We're racing with irq here. If we lose, the
Expand Down Expand Up @@ -1737,7 +1739,7 @@ static int ata_host_set_pio(struct ata_port *ap)
continue;

if (!dev->pio_mode) {
printk(KERN_WARNING "ata%u: no PIO support\n", ap->id);
printk(KERN_WARNING "ata%u: no PIO support for device %d.\n", ap->id, i);
return -1;
}

Expand Down Expand Up @@ -2863,6 +2865,8 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
ata_fill_sg(qc);
}

void ata_noop_qc_prep(struct ata_queued_cmd *qc) { }

/**
* ata_sg_init_one - Associate command with memory buffer
* @qc: Command to be associated
Expand Down Expand Up @@ -3907,7 +3911,6 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc)

case ATA_PROT_ATAPI:
case ATA_PROT_PIO:
case ATA_PROT_PIO_MULT:
if (ap->flags & ATA_FLAG_PIO_DMA)
return 1;

Expand Down Expand Up @@ -4199,14 +4202,17 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)

void ata_bmdma_irq_clear(struct ata_port *ap)
{
if (ap->flags & ATA_FLAG_MMIO) {
void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
writeb(readb(mmio), mmio);
} else {
unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
outb(inb(addr), addr);
}
if (!ap->ioaddr.bmdma_addr)
return;

if (ap->flags & ATA_FLAG_MMIO) {
void __iomem *mmio =
((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
writeb(readb(mmio), mmio);
} else {
unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
outb(inb(addr), addr);
}
}


Expand Down Expand Up @@ -4337,9 +4343,9 @@ inline unsigned int ata_host_intr (struct ata_port *ap,

#ifdef ATA_IRQ_TRAP
if ((ap->stats.idle_irq % 1000) == 0) {
handled = 1;
ata_irq_ack(ap, 0); /* debug trap */
printk(KERN_WARNING "ata%d: irq trap\n", ap->id);
return 1;
}
#endif
return 0; /* irq not handled */
Expand Down Expand Up @@ -5062,6 +5068,7 @@ EXPORT_SYMBOL_GPL(ata_port_stop);
EXPORT_SYMBOL_GPL(ata_host_stop);
EXPORT_SYMBOL_GPL(ata_interrupt);
EXPORT_SYMBOL_GPL(ata_qc_prep);
EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
EXPORT_SYMBOL_GPL(ata_bmdma_start);
EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
Expand Down
140 changes: 87 additions & 53 deletions trunk/drivers/scsi/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,13 +511,11 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n",
id, drv_stat);

/* For our last chance pick, use medium read error because
* it's much more common than an ATA drive telling you a write
* has failed.
*/
*sk = MEDIUM_ERROR;
*asc = 0x11; /* "unrecovered read error" */
*ascq = 0x04; /* "auto-reallocation failed" */
/* We need a sensible error return here, which is tricky, and one
that won't cause people to do things like return a disk wrongly */
*sk = ABORTED_COMMAND;
*asc = 0x00;
*ascq = 0x00;

translate_done:
printk(KERN_ERR "ata%u: translated ATA stat/err 0x%02x/%02x to "
Expand Down Expand Up @@ -662,6 +660,41 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
}
}

static void ata_scsi_sdev_config(struct scsi_device *sdev)
{
sdev->use_10_for_rw = 1;
sdev->use_10_for_ms = 1;
}

static void ata_scsi_dev_config(struct scsi_device *sdev,
struct ata_device *dev)
{
unsigned int max_sectors;

/* TODO: 2048 is an arbitrary number, not the
* hardware maximum. This should be increased to
* 65534 when Jens Axboe's patch for dynamically
* determining max_sectors is merged.
*/
max_sectors = ATA_MAX_SECTORS;
if (dev->flags & ATA_DFLAG_LBA48)
max_sectors = 2048;
if (dev->max_sectors)
max_sectors = dev->max_sectors;

blk_queue_max_sectors(sdev->request_queue, max_sectors);

/*
* SATA DMA transfers must be multiples of 4 byte, so
* we need to pad ATAPI transfers using an extra sg.
* Decrement max hw segments accordingly.
*/
if (dev->class == ATA_DEV_ATAPI) {
request_queue_t *q = sdev->request_queue;
blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
}
}

/**
* ata_scsi_slave_config - Set SCSI device attributes
* @sdev: SCSI device to examine
Expand All @@ -676,41 +709,18 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)

int ata_scsi_slave_config(struct scsi_device *sdev)
{
sdev->use_10_for_rw = 1;
sdev->use_10_for_ms = 1;
ata_scsi_sdev_config(sdev);

blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD);

if (sdev->id < ATA_MAX_DEVICES) {
struct ata_port *ap;
struct ata_device *dev;
unsigned int max_sectors;

ap = (struct ata_port *) &sdev->host->hostdata[0];
dev = &ap->device[sdev->id];

/* TODO: 2048 is an arbitrary number, not the
* hardware maximum. This should be increased to
* 65534 when Jens Axboe's patch for dynamically
* determining max_sectors is merged.
*/
max_sectors = ATA_MAX_SECTORS;
if (dev->flags & ATA_DFLAG_LBA48)
max_sectors = 2048;
if (dev->max_sectors)
max_sectors = dev->max_sectors;

blk_queue_max_sectors(sdev->request_queue, max_sectors);

/*
* SATA DMA transfers must be multiples of 4 byte, so
* we need to pad ATAPI transfers using an extra sg.
* Decrement max hw segments accordingly.
*/
if (dev->class == ATA_DEV_ATAPI) {
request_queue_t *q = sdev->request_queue;
blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
}
ata_scsi_dev_config(sdev, dev);
}

return 0; /* scsi layer doesn't check return value, sigh */
Expand Down Expand Up @@ -1542,7 +1552,7 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
* @buflen: Response buffer length.
*
* Returns standard device identification data associated
* with non-EVPD INQUIRY command output.
* with non-VPD INQUIRY command output.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
Expand Down Expand Up @@ -1593,12 +1603,12 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
}

/**
* ata_scsiop_inq_00 - Simulate INQUIRY EVPD page 0, list of pages
* ata_scsiop_inq_00 - Simulate INQUIRY VPD page 0, list of pages
* @args: device IDENTIFY data / SCSI command of interest.
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* @buflen: Response buffer length.
*
* Returns list of inquiry EVPD pages available.
* Returns list of inquiry VPD pages available.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
Expand All @@ -1612,7 +1622,7 @@ unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf,
0x80, /* page 0x80, unit serial no page */
0x83 /* page 0x83, device ident page */
};
rbuf[3] = sizeof(pages); /* number of supported EVPD pages */
rbuf[3] = sizeof(pages); /* number of supported VPD pages */

if (buflen > 6)
memcpy(rbuf + 4, pages, sizeof(pages));
Expand All @@ -1621,7 +1631,7 @@ unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf,
}

/**
* ata_scsiop_inq_80 - Simulate INQUIRY EVPD page 80, device serial number
* ata_scsiop_inq_80 - Simulate INQUIRY VPD page 80, device serial number
* @args: device IDENTIFY data / SCSI command of interest.
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* @buflen: Response buffer length.
Expand Down Expand Up @@ -1650,16 +1660,16 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf,
return 0;
}

static const char * const inq_83_str = "Linux ATA-SCSI simulator";

/**
* ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity
* ata_scsiop_inq_83 - Simulate INQUIRY VPD page 83, device identity
* @args: device IDENTIFY data / SCSI command of interest.
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* @buflen: Response buffer length.
*
* Returns device identification. Currently hardcoded to
* return "Linux ATA-SCSI simulator".
* Yields two logical unit device identification designators:
* - vendor specific ASCII containing the ATA serial number
* - SAT defined "t10 vendor id based" containing ASCII vendor
* name ("ATA "), model and serial numbers.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
Expand All @@ -1668,16 +1678,39 @@ static const char * const inq_83_str = "Linux ATA-SCSI simulator";
unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen)
{
rbuf[1] = 0x83; /* this page code */
rbuf[3] = 4 + strlen(inq_83_str); /* page len */
int num;
const int sat_model_serial_desc_len = 68;
const int ata_model_byte_len = 40;

/* our one and only identification descriptor (vendor-specific) */
if (buflen > (strlen(inq_83_str) + 4 + 4 - 1)) {
rbuf[4 + 0] = 2; /* code set: ASCII */
rbuf[4 + 3] = strlen(inq_83_str);
memcpy(rbuf + 4 + 4, inq_83_str, strlen(inq_83_str));
rbuf[1] = 0x83; /* this page code */
num = 4;

if (buflen > (ATA_SERNO_LEN + num + 3)) {
/* piv=0, assoc=lu, code_set=ACSII, designator=vendor */
rbuf[num + 0] = 2;
rbuf[num + 3] = ATA_SERNO_LEN;
num += 4;
ata_id_string(args->id, (unsigned char *) rbuf + num,
ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
num += ATA_SERNO_LEN;
}

if (buflen > (sat_model_serial_desc_len + num + 3)) {
/* SAT defined lu model and serial numbers descriptor */
/* piv=0, assoc=lu, code_set=ACSII, designator=t10 vendor id */
rbuf[num + 0] = 2;
rbuf[num + 1] = 1;
rbuf[num + 3] = sat_model_serial_desc_len;
num += 4;
memcpy(rbuf + num, "ATA ", 8);
num += 8;
ata_id_string(args->id, (unsigned char *) rbuf + num,
ATA_ID_PROD_OFS, ata_model_byte_len);
num += ata_model_byte_len;
ata_id_string(args->id, (unsigned char *) rbuf + num,
ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
num += ATA_SERNO_LEN;
}
rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */
return 0;
}

Expand Down Expand Up @@ -2356,9 +2389,6 @@ ata_scsi_map_proto(u8 byte1)

case 4: /* PIO Data-in */
case 5: /* PIO Data-out */
if (byte1 & 0xe0) {
return ATA_PROT_PIO_MULT;
}
return ATA_PROT_PIO;

case 10: /* Device Reset */
Expand Down Expand Up @@ -2397,6 +2427,10 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
goto invalid_fld;

if (scsicmd[1] & 0xe0)
/* PIO multi not supported yet */
goto invalid_fld;

/*
* 12 and 16 byte CDBs use different offsets to
* provide the various register values.
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/scsi/pdc_adma.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
= (pFLAGS & pEND) ? 0 : cpu_to_le32(pp->pkt_dma + i + 4);
i += 4;

VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", nelem,
VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4,
(unsigned long)addr, len);
}
return i;
Expand Down
Loading

0 comments on commit 09d86f5

Please sign in to comment.