aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_sil24.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2005-11-18 00:16:45 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-18 13:11:39 -0500
commit69ad185fa139b8fff2442d89440e382679d51f0f (patch)
tree4ff8b81de321a10e3a4fcb3f69fb8c4855b9e241 /drivers/scsi/sata_sil24.c
parentca45160db70661a006d884df07f82c9b51d27a52 (diff)
[PATCH] sil24: add ATAPI support
This patch implements ATAPI support for sil24 and bumps driver version to 0.23. Signed-off-by: Tejun Heo <htejun@gmail.com> -- Jeff, it has been converted to use ->dev_config as pointed out. Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/scsi/sata_sil24.c')
-rw-r--r--drivers/scsi/sata_sil24.c84
1 files changed, 58 insertions, 26 deletions
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 59aab163bcdc..340641fa1c68 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -5,17 +5,6 @@
5 * 5 *
6 * Based on preview driver from Silicon Image. 6 * Based on preview driver from Silicon Image.
7 * 7 *
8 * NOTE: No NCQ/ATAPI support yet. The preview driver didn't support
9 * NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make
10 * those work. Enabling those shouldn't be difficult. Basic
11 * structure is all there (in libata-dev tree). If you have any
12 * information about this hardware, please contact me or linux-ide.
13 * Info is needed on...
14 *
15 * - How to issue tagged commands and turn on sactive on issue accordingly.
16 * - Where to put an ATAPI command and how to tell the device to send it.
17 * - How to enable/use 64bit.
18 *
19 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
21 * Free Software Foundation; either version 2, or (at your option) any 10 * Free Software Foundation; either version 2, or (at your option) any
@@ -42,7 +31,7 @@
42#include <asm/io.h> 31#include <asm/io.h>
43 32
44#define DRV_NAME "sata_sil24" 33#define DRV_NAME "sata_sil24"
45#define DRV_VERSION "0.22" /* Silicon Image's preview driver was 0.10 */ 34#define DRV_VERSION "0.23"
46 35
47/* 36/*
48 * Port request block (PRB) 32 bytes 37 * Port request block (PRB) 32 bytes
@@ -221,11 +210,22 @@ enum {
221 IRQ_STAT_4PORTS = 0xf, 210 IRQ_STAT_4PORTS = 0xf,
222}; 211};
223 212
224struct sil24_cmd_block { 213struct sil24_ata_block {
225 struct sil24_prb prb; 214 struct sil24_prb prb;
226 struct sil24_sge sge[LIBATA_MAX_PRD]; 215 struct sil24_sge sge[LIBATA_MAX_PRD];
227}; 216};
228 217
218struct sil24_atapi_block {
219 struct sil24_prb prb;
220 u8 cdb[16];
221 struct sil24_sge sge[LIBATA_MAX_PRD - 1];
222};
223
224union sil24_cmd_block {
225 struct sil24_ata_block ata;
226 struct sil24_atapi_block atapi;
227};
228
229/* 229/*
230 * ap->private_data 230 * ap->private_data
231 * 231 *
@@ -233,7 +233,7 @@ struct sil24_cmd_block {
233 * here from the previous interrupt. 233 * here from the previous interrupt.
234 */ 234 */
235struct sil24_port_priv { 235struct sil24_port_priv {
236 struct sil24_cmd_block *cmd_block; /* 32 cmd blocks */ 236 union sil24_cmd_block *cmd_block; /* 32 cmd blocks */
237 dma_addr_t cmd_block_dma; /* DMA base addr for them */ 237 dma_addr_t cmd_block_dma; /* DMA base addr for them */
238 struct ata_taskfile tf; /* Cached taskfile registers */ 238 struct ata_taskfile tf; /* Cached taskfile registers */
239}; 239};
@@ -244,6 +244,7 @@ struct sil24_host_priv {
244 void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */ 244 void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */
245}; 245};
246 246
247static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev);
247static u8 sil24_check_status(struct ata_port *ap); 248static u8 sil24_check_status(struct ata_port *ap);
248static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); 249static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
249static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); 250static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
@@ -297,6 +298,8 @@ static struct scsi_host_template sil24_sht = {
297static const struct ata_port_operations sil24_ops = { 298static const struct ata_port_operations sil24_ops = {
298 .port_disable = ata_port_disable, 299 .port_disable = ata_port_disable,
299 300
301 .dev_config = sil24_dev_config,
302
300 .check_status = sil24_check_status, 303 .check_status = sil24_check_status,
301 .check_altstatus = sil24_check_status, 304 .check_altstatus = sil24_check_status,
302 .dev_select = ata_noop_dev_select, 305 .dev_select = ata_noop_dev_select,
@@ -364,6 +367,16 @@ static struct ata_port_info sil24_port_info[] = {
364 }, 367 },
365}; 368};
366 369
370static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
371{
372 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
373
374 if (ap->cdb_len == 16)
375 writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
376 else
377 writel(PORT_CS_CDB16, port + PORT_CTRL_CLR);
378}
379
367static inline void sil24_update_tf(struct ata_port *ap) 380static inline void sil24_update_tf(struct ata_port *ap)
368{ 381{
369 struct sil24_port_priv *pp = ap->private_data; 382 struct sil24_port_priv *pp = ap->private_data;
@@ -419,7 +432,7 @@ static int sil24_issue_SRST(struct ata_port *ap)
419{ 432{
420 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; 433 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
421 struct sil24_port_priv *pp = ap->private_data; 434 struct sil24_port_priv *pp = ap->private_data;
422 struct sil24_prb *prb = &pp->cmd_block[0].prb; 435 struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
423 dma_addr_t paddr = pp->cmd_block_dma; 436 dma_addr_t paddr = pp->cmd_block_dma;
424 u32 irq_enable, irq_stat; 437 u32 irq_enable, irq_stat;
425 int cnt; 438 int cnt;
@@ -477,16 +490,11 @@ static void sil24_phy_reset(struct ata_port *ap)
477 } 490 }
478 491
479 ap->device->class = ata_dev_classify(&pp->tf); 492 ap->device->class = ata_dev_classify(&pp->tf);
480
481 /* No ATAPI yet */
482 if (ap->device->class == ATA_DEV_ATAPI)
483 ap->ops->port_disable(ap);
484} 493}
485 494
486static inline void sil24_fill_sg(struct ata_queued_cmd *qc, 495static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
487 struct sil24_cmd_block *cb) 496 struct sil24_sge *sge)
488{ 497{
489 struct sil24_sge *sge = cb->sge;
490 struct scatterlist *sg; 498 struct scatterlist *sg;
491 unsigned int idx = 0; 499 unsigned int idx = 0;
492 500
@@ -507,23 +515,47 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
507{ 515{
508 struct ata_port *ap = qc->ap; 516 struct ata_port *ap = qc->ap;
509 struct sil24_port_priv *pp = ap->private_data; 517 struct sil24_port_priv *pp = ap->private_data;
510 struct sil24_cmd_block *cb = pp->cmd_block + qc->tag; 518 union sil24_cmd_block *cb = pp->cmd_block + qc->tag;
511 struct sil24_prb *prb = &cb->prb; 519 struct sil24_prb *prb;
520 struct sil24_sge *sge;
512 521
513 switch (qc->tf.protocol) { 522 switch (qc->tf.protocol) {
514 case ATA_PROT_PIO: 523 case ATA_PROT_PIO:
515 case ATA_PROT_DMA: 524 case ATA_PROT_DMA:
516 case ATA_PROT_NODATA: 525 case ATA_PROT_NODATA:
526 prb = &cb->ata.prb;
527 sge = cb->ata.sge;
528 prb->ctrl = 0;
517 break; 529 break;
530
531 case ATA_PROT_ATAPI:
532 case ATA_PROT_ATAPI_DMA:
533 case ATA_PROT_ATAPI_NODATA:
534 prb = &cb->atapi.prb;
535 sge = cb->atapi.sge;
536 memset(cb->atapi.cdb, 0, 32);
537 memcpy(cb->atapi.cdb, qc->cdb, ap->cdb_len);
538
539 if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) {
540 if (qc->tf.flags & ATA_TFLAG_WRITE)
541 prb->ctrl = PRB_CTRL_PACKET_WRITE;
542 else
543 prb->ctrl = PRB_CTRL_PACKET_READ;
544 } else
545 prb->ctrl = 0;
546
547 break;
548
518 default: 549 default:
519 /* ATAPI isn't supported yet */ 550 prb = NULL; /* shut up, gcc */
551 sge = NULL;
520 BUG(); 552 BUG();
521 } 553 }
522 554
523 ata_tf_to_fis(&qc->tf, prb->fis, 0); 555 ata_tf_to_fis(&qc->tf, prb->fis, 0);
524 556
525 if (qc->flags & ATA_QCFLAG_DMAMAP) 557 if (qc->flags & ATA_QCFLAG_DMAMAP)
526 sil24_fill_sg(qc, cb); 558 sil24_fill_sg(qc, sge);
527} 559}
528 560
529static int sil24_qc_issue(struct ata_queued_cmd *qc) 561static int sil24_qc_issue(struct ata_queued_cmd *qc)
@@ -750,7 +782,7 @@ static int sil24_port_start(struct ata_port *ap)
750{ 782{
751 struct device *dev = ap->host_set->dev; 783 struct device *dev = ap->host_set->dev;
752 struct sil24_port_priv *pp; 784 struct sil24_port_priv *pp;
753 struct sil24_cmd_block *cb; 785 union sil24_cmd_block *cb;
754 size_t cb_size = sizeof(*cb); 786 size_t cb_size = sizeof(*cb);
755 dma_addr_t cb_dma; 787 dma_addr_t cb_dma;
756 int rc = -ENOMEM; 788 int rc = -ENOMEM;