1/*- 2 * Copyright (c) 1998,1999 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 *
| 1/*- 2 * Copyright (c) 1998,1999 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 *
|
29 */ 30 31#include "ata.h" 32#include "pci.h" 33#if NATA > 0 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#include <sys/buf.h> 38#include <sys/malloc.h> 39#include <sys/bus.h> 40#include <vm/vm.h> 41#include <vm/pmap.h> 42#if NPCI > 0 43#include <pci/pcivar.h> 44#include <pci/pcireg.h> 45#endif 46#include <dev/ata/ata-all.h> 47 48#ifdef __alpha__ 49#undef vtophys 50#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) 51#endif 52 53/* misc defines */ 54#define MIN(a,b) ((a)>(b)?(b):(a)) 55 56#if NPCI > 0 57 58int32_t 59ata_dmainit(struct ata_softc *scp, int32_t device, 60 int32_t apiomode, int32_t wdmamode, int32_t udmamode) 61{ 62 int32_t type, devno, error; 63 void *dmatab; 64 65 if (!scp->bmaddr) 66 return -1; 67#ifdef ATA_DEBUGDMA 68 printf("ata%d: dmainit: ioaddr=0x%x altioaddr=0x%x, bmaddr=0x%x\n", 69 scp->lun, scp->ioaddr, scp->altioaddr, scp->bmaddr); 70#endif 71 72 if (!(dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT))) 73 return -1; 74 75 if (((uintptr_t)dmatab >> PAGE_SHIFT) ^ 76 (((uintptr_t)dmatab + PAGE_SIZE - 1) >> PAGE_SHIFT)) { 77 printf("ata_dmainit: dmatab crosses page boundary, no DMA\n"); 78 free(dmatab, M_DEVBUF); 79 return -1; 80 } 81 scp->dmatab[device ? 1 : 0] = dmatab; 82 83 type = pci_get_devid(scp->dev); 84 85 switch(type) { 86 87 case 0x71118086: /* Intel PIIX4 */ 88 if (udmamode >= 2) { 89 int32_t mask48, new48; 90 91 printf("ata%d: %s: setting up UDMA2 mode on PIIX4 chip ", 92 scp->lun, (device) ? "slave" : "master"); 93 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 94 ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 95 if (error) { 96 printf("failed\n"); 97 break; 98 } 99 printf("OK\n"); 100 devno = (scp->unit << 1) + (device ? 1 : 0); 101 mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 102 new48 = (1 << devno) + (2 << (16 + (devno << 2))); 103 pci_write_config(scp->dev, 0x48, 104 (pci_read_config(scp->dev, 0x48, 4) & 105 ~mask48) | new48, 4); 106 return 0; 107 } 108 /* FALLTHROUGH */ 109 110 case 0x70108086: /* Intel PIIX3 */ 111 if (wdmamode >= 2 && apiomode >= 4) { 112 int32_t mask40, new40, mask44, new44; 113 114 /* if SITRE not set doit for both channels */ 115 if (!((pci_read_config(scp->dev, 0x40, 4)>>(scp->unit<<8))&0x4000)){ 116 new40 = pci_read_config(scp->dev, 0x40, 4); 117 new44 = pci_read_config(scp->dev, 0x44, 4); 118 if (!(new40 & 0x00004000)) { 119 new44 &= ~0x0000000f; 120 new44 |= ((new40&0x00003000)>>10)|((new40&0x00000300)>>8); 121 } 122 if (!(new40 & 0x40000000)) { 123 new44 &= ~0x000000f0; 124 new44 |= ((new40&0x30000000)>>22)|((new40&0x03000000)>>20); 125 } 126 new40 |= 0x40004000; 127 pci_write_config(scp->dev, 0x40, new40, 4); 128 pci_write_config(scp->dev, 0x44, new44, 4); 129 } 130 printf("ata%d: %s: setting up WDMA2 mode on PIIX3/4 chip ", 131 scp->lun, (device) ? "slave" : "master"); 132 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 133 ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 134 if (error) { 135 printf("failed\n"); 136 break; 137 } 138 printf("OK\n"); 139 if (device == ATA_MASTER) { 140 mask40 = 0x0000330f; 141 new40 = 0x00002307; 142 mask44 = 0; 143 new44 = 0; 144 } else { 145 mask40 = 0x000000f0; 146 new40 = 0x00000070; 147 mask44 = 0x0000000f; 148 new44 = 0x0000000b; 149 } 150 if (scp->unit) { 151 mask40 <<= 16; 152 new40 <<= 16; 153 mask44 <<= 4; 154 new44 <<= 4; 155 } 156 pci_write_config(scp->dev, 0x40, 157 (pci_read_config(scp->dev, 0x40, 4) & 158 ~mask40) | new40, 4); 159 pci_write_config(scp->dev, 0x44, 160 (pci_read_config(scp->dev, 0x44, 4) & 161 ~mask44) | new44, 4); 162 return 0; 163 } 164 break; 165 166 case 0x12308086: /* Intel PIIX */ 167 /* probably not worth the trouble */ 168 break; 169 170 case 0x4d33105a: /* Promise Ultra/33 / FastTrack controllers */ 171 case 0x4d38105a: /* Promise Ultra/66 controllers */
| 29 */ 30 31#include "ata.h" 32#include "pci.h" 33#if NATA > 0 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#include <sys/buf.h> 38#include <sys/malloc.h> 39#include <sys/bus.h> 40#include <vm/vm.h> 41#include <vm/pmap.h> 42#if NPCI > 0 43#include <pci/pcivar.h> 44#include <pci/pcireg.h> 45#endif 46#include <dev/ata/ata-all.h> 47 48#ifdef __alpha__ 49#undef vtophys 50#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) 51#endif 52 53/* misc defines */ 54#define MIN(a,b) ((a)>(b)?(b):(a)) 55 56#if NPCI > 0 57 58int32_t 59ata_dmainit(struct ata_softc *scp, int32_t device, 60 int32_t apiomode, int32_t wdmamode, int32_t udmamode) 61{ 62 int32_t type, devno, error; 63 void *dmatab; 64 65 if (!scp->bmaddr) 66 return -1; 67#ifdef ATA_DEBUGDMA 68 printf("ata%d: dmainit: ioaddr=0x%x altioaddr=0x%x, bmaddr=0x%x\n", 69 scp->lun, scp->ioaddr, scp->altioaddr, scp->bmaddr); 70#endif 71 72 if (!(dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT))) 73 return -1; 74 75 if (((uintptr_t)dmatab >> PAGE_SHIFT) ^ 76 (((uintptr_t)dmatab + PAGE_SIZE - 1) >> PAGE_SHIFT)) { 77 printf("ata_dmainit: dmatab crosses page boundary, no DMA\n"); 78 free(dmatab, M_DEVBUF); 79 return -1; 80 } 81 scp->dmatab[device ? 1 : 0] = dmatab; 82 83 type = pci_get_devid(scp->dev); 84 85 switch(type) { 86 87 case 0x71118086: /* Intel PIIX4 */ 88 if (udmamode >= 2) { 89 int32_t mask48, new48; 90 91 printf("ata%d: %s: setting up UDMA2 mode on PIIX4 chip ", 92 scp->lun, (device) ? "slave" : "master"); 93 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 94 ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 95 if (error) { 96 printf("failed\n"); 97 break; 98 } 99 printf("OK\n"); 100 devno = (scp->unit << 1) + (device ? 1 : 0); 101 mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 102 new48 = (1 << devno) + (2 << (16 + (devno << 2))); 103 pci_write_config(scp->dev, 0x48, 104 (pci_read_config(scp->dev, 0x48, 4) & 105 ~mask48) | new48, 4); 106 return 0; 107 } 108 /* FALLTHROUGH */ 109 110 case 0x70108086: /* Intel PIIX3 */ 111 if (wdmamode >= 2 && apiomode >= 4) { 112 int32_t mask40, new40, mask44, new44; 113 114 /* if SITRE not set doit for both channels */ 115 if (!((pci_read_config(scp->dev, 0x40, 4)>>(scp->unit<<8))&0x4000)){ 116 new40 = pci_read_config(scp->dev, 0x40, 4); 117 new44 = pci_read_config(scp->dev, 0x44, 4); 118 if (!(new40 & 0x00004000)) { 119 new44 &= ~0x0000000f; 120 new44 |= ((new40&0x00003000)>>10)|((new40&0x00000300)>>8); 121 } 122 if (!(new40 & 0x40000000)) { 123 new44 &= ~0x000000f0; 124 new44 |= ((new40&0x30000000)>>22)|((new40&0x03000000)>>20); 125 } 126 new40 |= 0x40004000; 127 pci_write_config(scp->dev, 0x40, new40, 4); 128 pci_write_config(scp->dev, 0x44, new44, 4); 129 } 130 printf("ata%d: %s: setting up WDMA2 mode on PIIX3/4 chip ", 131 scp->lun, (device) ? "slave" : "master"); 132 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 133 ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 134 if (error) { 135 printf("failed\n"); 136 break; 137 } 138 printf("OK\n"); 139 if (device == ATA_MASTER) { 140 mask40 = 0x0000330f; 141 new40 = 0x00002307; 142 mask44 = 0; 143 new44 = 0; 144 } else { 145 mask40 = 0x000000f0; 146 new40 = 0x00000070; 147 mask44 = 0x0000000f; 148 new44 = 0x0000000b; 149 } 150 if (scp->unit) { 151 mask40 <<= 16; 152 new40 <<= 16; 153 mask44 <<= 4; 154 new44 <<= 4; 155 } 156 pci_write_config(scp->dev, 0x40, 157 (pci_read_config(scp->dev, 0x40, 4) & 158 ~mask40) | new40, 4); 159 pci_write_config(scp->dev, 0x44, 160 (pci_read_config(scp->dev, 0x44, 4) & 161 ~mask44) | new44, 4); 162 return 0; 163 } 164 break; 165 166 case 0x12308086: /* Intel PIIX */ 167 /* probably not worth the trouble */ 168 break; 169 170 case 0x4d33105a: /* Promise Ultra/33 / FastTrack controllers */ 171 case 0x4d38105a: /* Promise Ultra/66 controllers */
|
172 devno = (scp->unit << 1) + (device ? 1 : 0); 173 if (udmamode >=2) { 174 printf("ata%d: %s: setting up UDMA2 mode on Promise chip ", 175 scp->lun, (device) ? "slave" : "master"); 176 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 177 ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 178 if (error) { 179 printf("failed\n"); 180 break; 181 } 182 printf("OK\n"); 183 pci_write_config(scp->dev, 0x60 + (devno << 2), 0x004127f3, 4); 184 return 0; 185 } 186 else if (wdmamode >= 2 && apiomode >= 4) { 187 printf("ata%d: %s: setting up WDMA2 mode on Promise chip ", 188 scp->lun, (device) ? "slave" : "master"); 189 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 190 ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 191 if (error) { 192 printf("failed\n"); 193 break; 194 } 195 printf("OK\n"); 196 pci_write_config(scp->dev, 0x60 + (devno << 2), 0x004367f3, 4); 197 return 0; 198 } 199 else { 200 printf("ata%d: %s: setting up PIO mode on Promise chip OK\n", 201 scp->lun, (device) ? "slave" : "master"); 202 pci_write_config(scp->dev, 0x60 + (devno << 2), 0x004fe924, 4); 203 } 204 break; 205 206 case 0x522910b9: /* AcerLabs Aladdin IV/V */ 207 if (udmamode >=2) { 208 int32_t word54 = pci_read_config(scp->dev, 0x54, 4); 209 210 printf("ata%d: %s: setting up UDMA2 mode on Aladdin chip ", 211 scp->lun, (device) ? "slave" : "master"); 212 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 213 ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 214 if (error) { 215 printf("failed\n"); 216 break; 217 } 218 printf("OK\n"); 219 word54 |= 0x5555; 220 word54 |= (0x0000000A << (16 + (scp->unit << 3) + (device << 2))); 221 pci_write_config(scp->dev, 0x54, word54, 4); 222 return 0; 223 224 } 225 else if (wdmamode >= 2 && apiomode >= 4) { 226 printf("ata%d: %s: setting up WDMA2 mode on Aladdin chip ", 227 scp->lun, (device) ? "slave" : "master"); 228 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 229 ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 230 if (error) { 231 printf("failed\n"); 232 break; 233 } 234 printf("OK\n"); 235 return 0; 236 } 237 break; 238 239 default: /* well, we have no support for this, but try anyways */ 240 if ((wdmamode >= 2 && apiomode >= 4) || udmamode >= 2) { 241 printf("ata%d: %s: setting up generic WDMA2 mode ", 242 scp->lun, (device) ? "slave" : "master"); 243 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 244 ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 245 if (error) { 246 printf("failed\n"); 247 break; 248 } 249 printf("OK\n"); 250 return 0; 251 } 252 } 253 free(dmatab, M_DEVBUF); 254 return -1; 255} 256 257int32_t 258ata_dmasetup(struct ata_softc *scp, int32_t device, 259 int8_t *data, int32_t count, int32_t flags) 260{ 261 struct ata_dmaentry *dmatab; 262 u_int32_t dma_count, dma_base; 263 int32_t i = 0; 264 265#ifdef ATA_DEBUGDMA 266 printf("ata%d: dmasetup\n", scp->lun); 267#endif 268 if (((uintptr_t)data & 1) || (count & 1)) 269 return -1; 270 271 if (!count) { 272 printf("ata%d: zero length DMA transfer attempt on %s\n", 273 scp->lun, (device ? "slave" : "master")); 274 return -1; 275 } 276 277 dmatab = scp->dmatab[device ? 1 : 0]; 278 dma_base = vtophys(data); 279 dma_count = MIN(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK))); 280 data += dma_count; 281 count -= dma_count; 282 283 while (count) { 284 dmatab[i].base = dma_base; 285 dmatab[i].count = (dma_count & 0xffff); 286 i++; 287 if (i >= ATA_DMA_ENTRIES) { 288 printf("ata%d: too many segments in DMA table for %s\n", 289 scp->lun, (device ? "slave" : "master")); 290 return -1; 291 } 292 dma_base = vtophys(data); 293 dma_count = MIN(count, PAGE_SIZE); 294 data += MIN(count, PAGE_SIZE); 295 count -= MIN(count, PAGE_SIZE); 296 } 297#ifdef ATA_DEBUGDMA 298printf("ata_dmasetup: base=%08x count%08x\n", 299 dma_base, dma_count); 300#endif 301 dmatab[i].base = dma_base; 302 dmatab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT; 303 304 outl(scp->bmaddr + ATA_BMDTP_PORT, vtophys(dmatab)); 305#ifdef ATA_DEBUGDMA 306printf("dmatab=%08x %08x\n", vtophys(dmatab), inl(scp->bmaddr+ATA_BMDTP_PORT)); 307#endif 308 outb(scp->bmaddr + ATA_BMCMD_PORT, flags ? ATA_BMCMD_WRITE_READ:0); 309 outb(scp->bmaddr + ATA_BMSTAT_PORT, (inb(scp->bmaddr + ATA_BMSTAT_PORT) | 310 (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR))); 311 return 0; 312} 313 314void 315ata_dmastart(struct ata_softc *scp, int32_t device) 316{ 317#ifdef ATA_DEBUGDMA 318 printf("ata%d: dmastart\n", scp->lun); 319#endif 320 outb(scp->bmaddr + ATA_BMCMD_PORT, 321 inb(scp->bmaddr + ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP); 322} 323 324int32_t 325ata_dmadone(struct ata_softc *scp, int32_t device) 326{ 327#ifdef ATA_DEBUGDMA 328 printf("ata%d: dmadone\n", scp->lun); 329#endif 330 outb(scp->bmaddr + ATA_BMCMD_PORT, 331 inb(scp->bmaddr + ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); 332 return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 333} 334 335int32_t 336ata_dmastatus(struct ata_softc *scp, int32_t device) 337{ 338#ifdef ATA_DEBUGDMA 339 printf("ata%d: dmastatus\n", scp->lun); 340#endif 341 return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 342} 343 344#else /* NPCI > 0 */ 345 346int32_t 347ata_dmainit(struct ata_softc *scp, int32_t device, 348 int32_t piomode, int32_t wdmamode, int32_t udmamode) 349{ 350 return -1; 351} 352 353int32_t 354ata_dmasetup(struct ata_softc *scp, int32_t device, 355 int8_t *data, int32_t count, int32_t flags) 356{ 357 return -1; 358} 359 360void 361ata_dmastart(struct ata_softc *scp, int32_t device) 362{ 363} 364 365int32_t 366ata_dmadone(struct ata_softc *scp, int32_t device) 367{ 368 return -1; 369} 370 371int32_t 372ata_dmastatus(struct ata_softc *scp, int32_t device) 373{ 374 return -1; 375} 376 377#endif /* NPCI > 0 */ 378#endif /* NATA > 0 */
| 177 devno = (scp->unit << 1) + (device ? 1 : 0); 178 if (udmamode >=2) { 179 printf("ata%d: %s: setting up UDMA2 mode on Promise chip ", 180 scp->lun, (device) ? "slave" : "master"); 181 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 182 ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 183 if (error) { 184 printf("failed\n"); 185 break; 186 } 187 printf("OK\n"); 188 pci_write_config(scp->dev, 0x60 + (devno << 2), 0x004127f3, 4); 189 return 0; 190 } 191 else if (wdmamode >= 2 && apiomode >= 4) { 192 printf("ata%d: %s: setting up WDMA2 mode on Promise chip ", 193 scp->lun, (device) ? "slave" : "master"); 194 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 195 ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 196 if (error) { 197 printf("failed\n"); 198 break; 199 } 200 printf("OK\n"); 201 pci_write_config(scp->dev, 0x60 + (devno << 2), 0x004367f3, 4); 202 return 0; 203 } 204 else { 205 printf("ata%d: %s: setting up PIO mode on Promise chip OK\n", 206 scp->lun, (device) ? "slave" : "master"); 207 pci_write_config(scp->dev, 0x60 + (devno << 2), 0x004fe924, 4); 208 } 209 break; 210 211 case 0x522910b9: /* AcerLabs Aladdin IV/V */ 212 if (udmamode >=2) { 213 int32_t word54 = pci_read_config(scp->dev, 0x54, 4); 214 215 printf("ata%d: %s: setting up UDMA2 mode on Aladdin chip ", 216 scp->lun, (device) ? "slave" : "master"); 217 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 218 ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 219 if (error) { 220 printf("failed\n"); 221 break; 222 } 223 printf("OK\n"); 224 word54 |= 0x5555; 225 word54 |= (0x0000000A << (16 + (scp->unit << 3) + (device << 2))); 226 pci_write_config(scp->dev, 0x54, word54, 4); 227 return 0; 228 229 } 230 else if (wdmamode >= 2 && apiomode >= 4) { 231 printf("ata%d: %s: setting up WDMA2 mode on Aladdin chip ", 232 scp->lun, (device) ? "slave" : "master"); 233 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 234 ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 235 if (error) { 236 printf("failed\n"); 237 break; 238 } 239 printf("OK\n"); 240 return 0; 241 } 242 break; 243 244 default: /* well, we have no support for this, but try anyways */ 245 if ((wdmamode >= 2 && apiomode >= 4) || udmamode >= 2) { 246 printf("ata%d: %s: setting up generic WDMA2 mode ", 247 scp->lun, (device) ? "slave" : "master"); 248 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 249 ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR); 250 if (error) { 251 printf("failed\n"); 252 break; 253 } 254 printf("OK\n"); 255 return 0; 256 } 257 } 258 free(dmatab, M_DEVBUF); 259 return -1; 260} 261 262int32_t 263ata_dmasetup(struct ata_softc *scp, int32_t device, 264 int8_t *data, int32_t count, int32_t flags) 265{ 266 struct ata_dmaentry *dmatab; 267 u_int32_t dma_count, dma_base; 268 int32_t i = 0; 269 270#ifdef ATA_DEBUGDMA 271 printf("ata%d: dmasetup\n", scp->lun); 272#endif 273 if (((uintptr_t)data & 1) || (count & 1)) 274 return -1; 275 276 if (!count) { 277 printf("ata%d: zero length DMA transfer attempt on %s\n", 278 scp->lun, (device ? "slave" : "master")); 279 return -1; 280 } 281 282 dmatab = scp->dmatab[device ? 1 : 0]; 283 dma_base = vtophys(data); 284 dma_count = MIN(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK))); 285 data += dma_count; 286 count -= dma_count; 287 288 while (count) { 289 dmatab[i].base = dma_base; 290 dmatab[i].count = (dma_count & 0xffff); 291 i++; 292 if (i >= ATA_DMA_ENTRIES) { 293 printf("ata%d: too many segments in DMA table for %s\n", 294 scp->lun, (device ? "slave" : "master")); 295 return -1; 296 } 297 dma_base = vtophys(data); 298 dma_count = MIN(count, PAGE_SIZE); 299 data += MIN(count, PAGE_SIZE); 300 count -= MIN(count, PAGE_SIZE); 301 } 302#ifdef ATA_DEBUGDMA 303printf("ata_dmasetup: base=%08x count%08x\n", 304 dma_base, dma_count); 305#endif 306 dmatab[i].base = dma_base; 307 dmatab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT; 308 309 outl(scp->bmaddr + ATA_BMDTP_PORT, vtophys(dmatab)); 310#ifdef ATA_DEBUGDMA 311printf("dmatab=%08x %08x\n", vtophys(dmatab), inl(scp->bmaddr+ATA_BMDTP_PORT)); 312#endif 313 outb(scp->bmaddr + ATA_BMCMD_PORT, flags ? ATA_BMCMD_WRITE_READ:0); 314 outb(scp->bmaddr + ATA_BMSTAT_PORT, (inb(scp->bmaddr + ATA_BMSTAT_PORT) | 315 (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR))); 316 return 0; 317} 318 319void 320ata_dmastart(struct ata_softc *scp, int32_t device) 321{ 322#ifdef ATA_DEBUGDMA 323 printf("ata%d: dmastart\n", scp->lun); 324#endif 325 outb(scp->bmaddr + ATA_BMCMD_PORT, 326 inb(scp->bmaddr + ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP); 327} 328 329int32_t 330ata_dmadone(struct ata_softc *scp, int32_t device) 331{ 332#ifdef ATA_DEBUGDMA 333 printf("ata%d: dmadone\n", scp->lun); 334#endif 335 outb(scp->bmaddr + ATA_BMCMD_PORT, 336 inb(scp->bmaddr + ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); 337 return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 338} 339 340int32_t 341ata_dmastatus(struct ata_softc *scp, int32_t device) 342{ 343#ifdef ATA_DEBUGDMA 344 printf("ata%d: dmastatus\n", scp->lun); 345#endif 346 return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 347} 348 349#else /* NPCI > 0 */ 350 351int32_t 352ata_dmainit(struct ata_softc *scp, int32_t device, 353 int32_t piomode, int32_t wdmamode, int32_t udmamode) 354{ 355 return -1; 356} 357 358int32_t 359ata_dmasetup(struct ata_softc *scp, int32_t device, 360 int8_t *data, int32_t count, int32_t flags) 361{ 362 return -1; 363} 364 365void 366ata_dmastart(struct ata_softc *scp, int32_t device) 367{ 368} 369 370int32_t 371ata_dmadone(struct ata_softc *scp, int32_t device) 372{ 373 return -1; 374} 375 376int32_t 377ata_dmastatus(struct ata_softc *scp, int32_t device) 378{ 379 return -1; 380} 381 382#endif /* NPCI > 0 */ 383#endif /* NATA > 0 */
|