Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.12-rc3 407 lines 11 kB view raw
1/* 2 * sata_vsc.c - Vitesse VSC7174 4 port DPA SATA 3 * 4 * Maintained by: Jeremy Higdon @ SGI 5 * Please ALWAYS copy linux-ide@vger.kernel.org 6 * on emails. 7 * 8 * Copyright 2004 SGI 9 * 10 * Bits from Jeff Garzik, Copyright RedHat, Inc. 11 * 12 * This file is subject to the terms and conditions of the GNU General Public 13 * License. See the file "COPYING" in the main directory of this archive 14 * for more details. 15 */ 16 17#include <linux/kernel.h> 18#include <linux/module.h> 19#include <linux/pci.h> 20#include <linux/init.h> 21#include <linux/blkdev.h> 22#include <linux/delay.h> 23#include <linux/interrupt.h> 24#include "scsi.h" 25#include <scsi/scsi_host.h> 26#include <linux/libata.h> 27 28#define DRV_NAME "sata_vsc" 29#define DRV_VERSION "1.0" 30 31/* Interrupt register offsets (from chip base address) */ 32#define VSC_SATA_INT_STAT_OFFSET 0x00 33#define VSC_SATA_INT_MASK_OFFSET 0x04 34 35/* Taskfile registers offsets */ 36#define VSC_SATA_TF_CMD_OFFSET 0x00 37#define VSC_SATA_TF_DATA_OFFSET 0x00 38#define VSC_SATA_TF_ERROR_OFFSET 0x04 39#define VSC_SATA_TF_FEATURE_OFFSET 0x06 40#define VSC_SATA_TF_NSECT_OFFSET 0x08 41#define VSC_SATA_TF_LBAL_OFFSET 0x0c 42#define VSC_SATA_TF_LBAM_OFFSET 0x10 43#define VSC_SATA_TF_LBAH_OFFSET 0x14 44#define VSC_SATA_TF_DEVICE_OFFSET 0x18 45#define VSC_SATA_TF_STATUS_OFFSET 0x1c 46#define VSC_SATA_TF_COMMAND_OFFSET 0x1d 47#define VSC_SATA_TF_ALTSTATUS_OFFSET 0x28 48#define VSC_SATA_TF_CTL_OFFSET 0x29 49 50/* DMA base */ 51#define VSC_SATA_UP_DESCRIPTOR_OFFSET 0x64 52#define VSC_SATA_UP_DATA_BUFFER_OFFSET 0x6C 53#define VSC_SATA_DMA_CMD_OFFSET 0x70 54 55/* SCRs base */ 56#define VSC_SATA_SCR_STATUS_OFFSET 0x100 57#define VSC_SATA_SCR_ERROR_OFFSET 0x104 58#define VSC_SATA_SCR_CONTROL_OFFSET 0x108 59 60/* Port stride */ 61#define VSC_SATA_PORT_OFFSET 0x200 62 63 64static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) 65{ 66 if (sc_reg > SCR_CONTROL) 67 return 0xffffffffU; 68 return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4)); 69} 70 71 72static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, 73 u32 val) 74{ 75 if (sc_reg > SCR_CONTROL) 76 return; 77 writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4)); 78} 79 80 81static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl) 82{ 83 unsigned long mask_addr; 84 u8 mask; 85 86 mask_addr = (unsigned long) ap->host_set->mmio_base + 87 VSC_SATA_INT_MASK_OFFSET + ap->port_no; 88 mask = readb(mask_addr); 89 if (ctl & ATA_NIEN) 90 mask |= 0x80; 91 else 92 mask &= 0x7F; 93 writeb(mask, mask_addr); 94} 95 96 97static void vsc_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) 98{ 99 struct ata_ioports *ioaddr = &ap->ioaddr; 100 unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; 101 102 /* 103 * The only thing the ctl register is used for is SRST. 104 * That is not enabled or disabled via tf_load. 105 * However, if ATA_NIEN is changed, then we need to change the interrupt register. 106 */ 107 if ((tf->ctl & ATA_NIEN) != (ap->last_ctl & ATA_NIEN)) { 108 ap->last_ctl = tf->ctl; 109 vsc_intr_mask_update(ap, tf->ctl & ATA_NIEN); 110 } 111 if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { 112 writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr); 113 writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr); 114 writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr); 115 writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr); 116 writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr); 117 } else if (is_addr) { 118 writew(tf->feature, ioaddr->feature_addr); 119 writew(tf->nsect, ioaddr->nsect_addr); 120 writew(tf->lbal, ioaddr->lbal_addr); 121 writew(tf->lbam, ioaddr->lbam_addr); 122 writew(tf->lbah, ioaddr->lbah_addr); 123 } 124 125 if (tf->flags & ATA_TFLAG_DEVICE) 126 writeb(tf->device, ioaddr->device_addr); 127 128 ata_wait_idle(ap); 129} 130 131 132static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) 133{ 134 struct ata_ioports *ioaddr = &ap->ioaddr; 135 u16 nsect, lbal, lbam, lbah; 136 137 nsect = tf->nsect = readw(ioaddr->nsect_addr); 138 lbal = tf->lbal = readw(ioaddr->lbal_addr); 139 lbam = tf->lbam = readw(ioaddr->lbam_addr); 140 lbah = tf->lbah = readw(ioaddr->lbah_addr); 141 tf->device = readw(ioaddr->device_addr); 142 143 if (tf->flags & ATA_TFLAG_LBA48) { 144 tf->hob_feature = readb(ioaddr->error_addr); 145 tf->hob_nsect = nsect >> 8; 146 tf->hob_lbal = lbal >> 8; 147 tf->hob_lbam = lbam >> 8; 148 tf->hob_lbah = lbah >> 8; 149 } 150} 151 152 153/* 154 * vsc_sata_interrupt 155 * 156 * Read the interrupt register and process for the devices that have them pending. 157 */ 158static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, 159 struct pt_regs *regs) 160{ 161 struct ata_host_set *host_set = dev_instance; 162 unsigned int i; 163 unsigned int handled = 0; 164 u32 int_status; 165 166 spin_lock(&host_set->lock); 167 168 int_status = readl(host_set->mmio_base + VSC_SATA_INT_STAT_OFFSET); 169 170 for (i = 0; i < host_set->n_ports; i++) { 171 if (int_status & ((u32) 0xFF << (8 * i))) { 172 struct ata_port *ap; 173 174 ap = host_set->ports[i]; 175 if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { 176 struct ata_queued_cmd *qc; 177 178 qc = ata_qc_from_tag(ap, ap->active_tag); 179 if (qc && (!(qc->tf.ctl & ATA_NIEN))) 180 handled += ata_host_intr(ap, qc); 181 } 182 } 183 } 184 185 spin_unlock(&host_set->lock); 186 187 return IRQ_RETVAL(handled); 188} 189 190 191static Scsi_Host_Template vsc_sata_sht = { 192 .module = THIS_MODULE, 193 .name = DRV_NAME, 194 .ioctl = ata_scsi_ioctl, 195 .queuecommand = ata_scsi_queuecmd, 196 .eh_strategy_handler = ata_scsi_error, 197 .can_queue = ATA_DEF_QUEUE, 198 .this_id = ATA_SHT_THIS_ID, 199 .sg_tablesize = LIBATA_MAX_PRD, 200 .max_sectors = ATA_MAX_SECTORS, 201 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 202 .emulated = ATA_SHT_EMULATED, 203 .use_clustering = ATA_SHT_USE_CLUSTERING, 204 .proc_name = DRV_NAME, 205 .dma_boundary = ATA_DMA_BOUNDARY, 206 .slave_configure = ata_scsi_slave_config, 207 .bios_param = ata_std_bios_param, 208 .ordered_flush = 1, 209}; 210 211 212static struct ata_port_operations vsc_sata_ops = { 213 .port_disable = ata_port_disable, 214 .tf_load = vsc_sata_tf_load, 215 .tf_read = vsc_sata_tf_read, 216 .exec_command = ata_exec_command, 217 .check_status = ata_check_status, 218 .dev_select = ata_std_dev_select, 219 .phy_reset = sata_phy_reset, 220 .bmdma_setup = ata_bmdma_setup, 221 .bmdma_start = ata_bmdma_start, 222 .bmdma_stop = ata_bmdma_stop, 223 .bmdma_status = ata_bmdma_status, 224 .qc_prep = ata_qc_prep, 225 .qc_issue = ata_qc_issue_prot, 226 .eng_timeout = ata_eng_timeout, 227 .irq_handler = vsc_sata_interrupt, 228 .irq_clear = ata_bmdma_irq_clear, 229 .scr_read = vsc_sata_scr_read, 230 .scr_write = vsc_sata_scr_write, 231 .port_start = ata_port_start, 232 .port_stop = ata_port_stop, 233}; 234 235static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base) 236{ 237 port->cmd_addr = base + VSC_SATA_TF_CMD_OFFSET; 238 port->data_addr = base + VSC_SATA_TF_DATA_OFFSET; 239 port->error_addr = base + VSC_SATA_TF_ERROR_OFFSET; 240 port->feature_addr = base + VSC_SATA_TF_FEATURE_OFFSET; 241 port->nsect_addr = base + VSC_SATA_TF_NSECT_OFFSET; 242 port->lbal_addr = base + VSC_SATA_TF_LBAL_OFFSET; 243 port->lbam_addr = base + VSC_SATA_TF_LBAM_OFFSET; 244 port->lbah_addr = base + VSC_SATA_TF_LBAH_OFFSET; 245 port->device_addr = base + VSC_SATA_TF_DEVICE_OFFSET; 246 port->status_addr = base + VSC_SATA_TF_STATUS_OFFSET; 247 port->command_addr = base + VSC_SATA_TF_COMMAND_OFFSET; 248 port->altstatus_addr = base + VSC_SATA_TF_ALTSTATUS_OFFSET; 249 port->ctl_addr = base + VSC_SATA_TF_CTL_OFFSET; 250 port->bmdma_addr = base + VSC_SATA_DMA_CMD_OFFSET; 251 port->scr_addr = base + VSC_SATA_SCR_STATUS_OFFSET; 252 writel(0, base + VSC_SATA_UP_DESCRIPTOR_OFFSET); 253 writel(0, base + VSC_SATA_UP_DATA_BUFFER_OFFSET); 254} 255 256 257static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) 258{ 259 static int printed_version; 260 struct ata_probe_ent *probe_ent = NULL; 261 unsigned long base; 262 int pci_dev_busy = 0; 263 void *mmio_base; 264 int rc; 265 266 if (!printed_version++) 267 printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); 268 269 rc = pci_enable_device(pdev); 270 if (rc) 271 return rc; 272 273 /* 274 * Check if we have needed resource mapped. 275 */ 276 if (pci_resource_len(pdev, 0) == 0) { 277 rc = -ENODEV; 278 goto err_out; 279 } 280 281 rc = pci_request_regions(pdev, DRV_NAME); 282 if (rc) { 283 pci_dev_busy = 1; 284 goto err_out; 285 } 286 287 /* 288 * Use 32 bit DMA mask, because 64 bit address support is poor. 289 */ 290 rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); 291 if (rc) 292 goto err_out_regions; 293 rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); 294 if (rc) 295 goto err_out_regions; 296 297 probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); 298 if (probe_ent == NULL) { 299 rc = -ENOMEM; 300 goto err_out_regions; 301 } 302 memset(probe_ent, 0, sizeof(*probe_ent)); 303 probe_ent->dev = pci_dev_to_dev(pdev); 304 INIT_LIST_HEAD(&probe_ent->node); 305 306 mmio_base = ioremap(pci_resource_start(pdev, 0), 307 pci_resource_len(pdev, 0)); 308 if (mmio_base == NULL) { 309 rc = -ENOMEM; 310 goto err_out_free_ent; 311 } 312 base = (unsigned long) mmio_base; 313 314 /* 315 * Due to a bug in the chip, the default cache line size can't be used 316 */ 317 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x80); 318 319 probe_ent->sht = &vsc_sata_sht; 320 probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 321 ATA_FLAG_MMIO | ATA_FLAG_SATA_RESET; 322 probe_ent->port_ops = &vsc_sata_ops; 323 probe_ent->n_ports = 4; 324 probe_ent->irq = pdev->irq; 325 probe_ent->irq_flags = SA_SHIRQ; 326 probe_ent->mmio_base = mmio_base; 327 328 /* We don't care much about the PIO/UDMA masks, but the core won't like us 329 * if we don't fill these 330 */ 331 probe_ent->pio_mask = 0x1f; 332 probe_ent->mwdma_mask = 0x07; 333 probe_ent->udma_mask = 0x7f; 334 335 /* We have 4 ports per PCI function */ 336 vsc_sata_setup_port(&probe_ent->port[0], base + 1 * VSC_SATA_PORT_OFFSET); 337 vsc_sata_setup_port(&probe_ent->port[1], base + 2 * VSC_SATA_PORT_OFFSET); 338 vsc_sata_setup_port(&probe_ent->port[2], base + 3 * VSC_SATA_PORT_OFFSET); 339 vsc_sata_setup_port(&probe_ent->port[3], base + 4 * VSC_SATA_PORT_OFFSET); 340 341 pci_set_master(pdev); 342 343 /* 344 * Config offset 0x98 is "Extended Control and Status Register 0" 345 * Default value is (1 << 28). All bits except bit 28 are reserved in 346 * DPA mode. If bit 28 is set, LED 0 reflects all ports' activity. 347 * If bit 28 is clear, each port has its own LED. 348 */ 349 pci_write_config_dword(pdev, 0x98, 0); 350 351 /* FIXME: check ata_device_add return value */ 352 ata_device_add(probe_ent); 353 kfree(probe_ent); 354 355 return 0; 356 357err_out_free_ent: 358 kfree(probe_ent); 359err_out_regions: 360 pci_release_regions(pdev); 361err_out: 362 if (!pci_dev_busy) 363 pci_disable_device(pdev); 364 return rc; 365} 366 367 368/* 369 * 0x1725/0x7174 is the Vitesse VSC-7174 370 * 0x8086/0x3200 is the Intel 31244, which is supposed to be identical 371 * compatibility is untested as of yet 372 */ 373static struct pci_device_id vsc_sata_pci_tbl[] = { 374 { 0x1725, 0x7174, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, 375 { 0x8086, 0x3200, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, 376 { } 377}; 378 379 380static struct pci_driver vsc_sata_pci_driver = { 381 .name = DRV_NAME, 382 .id_table = vsc_sata_pci_tbl, 383 .probe = vsc_sata_init_one, 384 .remove = ata_pci_remove_one, 385}; 386 387 388static int __init vsc_sata_init(void) 389{ 390 return pci_module_init(&vsc_sata_pci_driver); 391} 392 393 394static void __exit vsc_sata_exit(void) 395{ 396 pci_unregister_driver(&vsc_sata_pci_driver); 397} 398 399 400MODULE_AUTHOR("Jeremy Higdon"); 401MODULE_DESCRIPTION("low-level driver for Vitesse VSC7174 SATA controller"); 402MODULE_LICENSE("GPL"); 403MODULE_DEVICE_TABLE(pci, vsc_sata_pci_tbl); 404MODULE_VERSION(DRV_VERSION); 405 406module_init(vsc_sata_init); 407module_exit(vsc_sata_exit);