]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ata/ata-disk.c
This commit was generated by cvs2svn to compensate for changes in r146611,
[FreeBSD/FreeBSD.git] / sys / dev / ata / ata-disk.c
1 /*-
2  * Copyright (c) 1998 - 2005 Søren Schmidt <sos@FreeBSD.org>
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  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include "opt_ata.h"
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/ata.h>
36 #include <sys/kernel.h>
37 #include <sys/module.h>
38 #include <sys/malloc.h>
39 #include <sys/bio.h>
40 #include <sys/bus.h>
41 #include <sys/conf.h>
42 #include <sys/disk.h>
43 #include <sys/cons.h>
44 #include <sys/sysctl.h>
45 #include <sys/sema.h>
46 #include <sys/taskqueue.h>
47 #include <vm/uma.h>
48 #include <machine/md_var.h>
49 #include <machine/bus.h>
50 #include <sys/rman.h>
51 #include <geom/geom_disk.h>
52 #include <dev/ata/ata-all.h>
53 #include <dev/ata/ata-pci.h>
54 #include <dev/ata/ata-disk.h>
55 #include <dev/ata/ata-raid.h>
56 #include <ata_if.h>
57
58 /* prototypes */
59 static void ad_init(device_t);
60 static void ad_done(struct ata_request *);
61 static void ad_describe(device_t dev);
62 static int ad_version(u_int16_t);
63 static disk_strategy_t ad_strategy;
64 static disk_ioctl_t ad_ioctl;
65 static dumper_t ad_dump;
66
67 /* local vars */
68 static MALLOC_DEFINE(M_AD, "AD driver", "ATA disk driver");
69
70 static int
71 ad_probe(device_t dev)
72 {
73     struct ata_device *atadev = device_get_softc(dev);
74
75     if (!(atadev->param.config & ATA_PROTO_ATAPI) ||
76         (atadev->param.config == ATA_CFA_MAGIC))
77         return 0;
78     else
79         return ENXIO;
80 }
81
82 static int
83 ad_attach(device_t dev)
84 {
85     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
86     struct ata_device *atadev = device_get_softc(dev);
87     struct ad_softc *adp;
88     u_int32_t lbasize;
89     u_int64_t lbasize48;
90
91     /* check that we have a virgin disk to attach */
92     if (device_get_ivars(dev))
93         return EEXIST;
94
95     if (!(adp = malloc(sizeof(struct ad_softc), M_AD, M_NOWAIT | M_ZERO))) {
96         device_printf(dev, "out of memory\n");
97         return ENOMEM;
98     }
99     device_set_ivars(dev, adp);
100
101     if (atadev->param.atavalid & ATA_FLAG_54_58) {
102         adp->heads = atadev->param.current_heads;
103         adp->sectors = atadev->param.current_sectors;
104         adp->total_secs = (u_int32_t)atadev->param.current_size_1 |
105                           ((u_int32_t)atadev->param.current_size_2 << 16);
106     }
107     else {
108         adp->heads = atadev->param.heads;
109         adp->sectors = atadev->param.sectors;
110         adp->total_secs = atadev->param.cylinders * adp->heads * adp->sectors;  
111     }
112     lbasize = (u_int32_t)atadev->param.lba_size_1 |
113               ((u_int32_t)atadev->param.lba_size_2 << 16);
114
115     /* does this device need oldstyle CHS addressing */
116     if (!ad_version(atadev->param.version_major) || !lbasize)
117         atadev->flags |= ATA_D_USE_CHS;
118
119     /* use the 28bit LBA size if valid or bigger than the CHS mapping */
120     if (atadev->param.cylinders == 16383 || adp->total_secs < lbasize)
121         adp->total_secs = lbasize;
122
123     /* use the 48bit LBA size if valid */
124     lbasize48 = ((u_int64_t)atadev->param.lba_size48_1) |
125                 ((u_int64_t)atadev->param.lba_size48_2 << 16) |
126                 ((u_int64_t)atadev->param.lba_size48_3 << 32) |
127                 ((u_int64_t)atadev->param.lba_size48_4 << 48);
128     if ((atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) &&
129         lbasize48 > ATA_MAX_28BIT_LBA)
130         adp->total_secs = lbasize48;
131
132     /* init device parameters */
133     ad_init(dev);
134
135     /* announce we are here */
136     ad_describe(dev);
137
138     /* create the disk device */
139     adp->disk = disk_alloc();
140     adp->disk->d_strategy = ad_strategy;
141     adp->disk->d_ioctl = ad_ioctl;
142     adp->disk->d_dump = ad_dump;
143     adp->disk->d_name = "ad";
144     adp->disk->d_drv1 = dev;
145     if (ch->dma)
146         adp->disk->d_maxsize = ch->dma->max_iosize;
147     else
148         adp->disk->d_maxsize = DFLTPHYS;
149     adp->disk->d_sectorsize = DEV_BSIZE;
150     adp->disk->d_mediasize = DEV_BSIZE * (off_t)adp->total_secs;
151     adp->disk->d_fwsectors = adp->sectors;
152     adp->disk->d_fwheads = adp->heads;
153     adp->disk->d_unit = device_get_unit(dev);
154     disk_create(adp->disk, DISK_VERSION);
155     device_add_child(dev, "subdisk", device_get_unit(dev));
156     bus_generic_attach(dev);
157     return 0;
158 }
159
160 static int
161 ad_detach(device_t dev)
162 {
163     struct ad_softc *adp = device_get_ivars(dev);
164     device_t *children;
165     int nchildren, i;
166
167     /* check that we have a valid disk to detach */
168     if (!device_get_ivars(dev))
169         return ENXIO;
170     
171     /* detach & delete all children */
172     if (!device_get_children(dev, &children, &nchildren)) {
173         for (i = 0; i < nchildren; i++)
174             if (children[i])
175                 device_delete_child(dev, children[i]);
176         free(children, M_TEMP);
177     }
178
179     /* detroy disk from the system so we dont get any further requests */
180     disk_destroy(adp->disk);
181
182     /* fail requests on the queue and any thats "in flight" for this device */
183     ata_fail_requests(dev);
184
185     /* dont leave anything behind */
186     device_set_ivars(dev, NULL);
187     free(adp, M_AD);
188     return 0;
189 }
190
191 static void
192 ad_shutdown(device_t dev)
193 {
194     struct ata_device *atadev = device_get_softc(dev);
195
196     if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE)
197         ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0);
198 }
199
200 static int
201 ad_reinit(device_t dev)
202 {
203     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
204     struct ata_device *atadev = device_get_softc(dev);
205
206     /* if detach pending flag set, return error */
207
208     if (((atadev->unit == ATA_MASTER) && !(ch->devices & ATA_ATA_MASTER)) ||
209         ((atadev->unit == ATA_SLAVE) && !(ch->devices & ATA_ATA_SLAVE))) {
210         return 1;
211     }
212     ad_init(dev);
213     return 0;
214 }
215
216 static void 
217 ad_strategy(struct bio *bp)
218 {
219     device_t dev =  bp->bio_disk->d_drv1;
220     struct ata_device *atadev = device_get_softc(dev);
221     struct ata_request *request;
222
223     if (!(request = ata_alloc_request())) {
224         device_printf(dev, "FAILURE - out of memory in start\n");
225         biofinish(bp, NULL, ENOMEM);
226         return;
227     }
228
229     /* setup request */
230     request->dev = dev;
231     request->bio = bp;
232     request->callback = ad_done;
233     request->timeout = 5;
234     request->retries = 2;
235     request->data = bp->bio_data;
236     request->bytecount = bp->bio_bcount;
237     request->u.ata.lba = bp->bio_pblkno;
238     request->u.ata.count = request->bytecount / DEV_BSIZE;
239     request->transfersize = min(bp->bio_bcount, atadev->max_iosize);
240
241     switch (bp->bio_cmd) {
242     case BIO_READ:
243         request->flags = ATA_R_READ;
244         if (atadev->mode >= ATA_DMA) {
245             request->u.ata.command = ATA_READ_DMA;
246             request->flags |= ATA_R_DMA;
247         }
248         else if (atadev->max_iosize > DEV_BSIZE)
249             request->u.ata.command = ATA_READ_MUL;
250         else
251             request->u.ata.command = ATA_READ;
252         break;
253     case BIO_WRITE:
254         request->flags = ATA_R_WRITE;
255         if (atadev->mode >= ATA_DMA) {
256             request->u.ata.command = ATA_WRITE_DMA;
257             request->flags |= ATA_R_DMA;
258         }
259         else if (atadev->max_iosize > DEV_BSIZE)
260             request->u.ata.command = ATA_WRITE_MUL;
261         else
262             request->u.ata.command = ATA_WRITE;
263         break;
264     default:
265         device_printf(dev, "FAILURE - unknown BIO operation\n");
266         ata_free_request(request);
267         biofinish(bp, NULL, EIO);
268         return;
269     }
270     request->flags |= ATA_R_ORDERED;
271     ata_queue_request(request);
272 }
273
274 static void
275 ad_done(struct ata_request *request)
276 {
277     struct bio *bp = request->bio;
278
279     /* finish up transfer */
280     if ((bp->bio_error = request->result))
281         bp->bio_flags |= BIO_ERROR;
282     bp->bio_resid = bp->bio_bcount - request->donecount;
283     biodone(bp);
284     ata_free_request(request);
285 }
286
287 static int
288 ad_ioctl(struct disk *disk, u_long cmd, void *data, int flag, struct thread *td)
289 {
290     return ata_device_ioctl(disk->d_drv1, cmd, data);
291 }
292
293 static int
294 ad_dump(void *arg, void *virtual, vm_offset_t physical,
295        off_t offset, size_t length)
296 {
297     struct disk *dp = arg;
298     device_t dev = dp->d_drv1;
299     struct ata_device *atadev = device_get_softc(dev);
300     struct ad_softc *adp = device_get_ivars(dev);
301     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
302     struct ata_request request;
303
304     if (!adp)
305         return ENXIO;
306
307     bzero(&request, sizeof(struct ata_request));
308     request.dev = dev;
309
310     if (length) {
311         request.data = virtual;
312         request.bytecount = length;
313         request.transfersize = min(length, atadev->max_iosize);
314         request.flags = ATA_R_WRITE;
315         if (atadev->max_iosize > DEV_BSIZE)
316             request.u.ata.command = ATA_WRITE_MUL;
317         else
318             request.u.ata.command = ATA_WRITE;
319         request.u.ata.lba = offset / DEV_BSIZE;
320         request.u.ata.count = request.bytecount / DEV_BSIZE;
321     }
322     else {
323         request.u.ata.command = ATA_FLUSHCACHE;
324         request.flags = ATA_R_CONTROL;
325     }
326     if (ch->hw.begin_transaction(&request) == ATA_OP_CONTINUES) {
327         do {
328             DELAY(20);
329         } while (ch->hw.end_transaction(&request) == ATA_OP_CONTINUES);
330         ata_finish(&request);
331     }
332     if (request.status & ATA_S_ERROR)
333         return EIO;
334     return 0;
335 }
336
337 static void
338 ad_init(device_t dev)
339 {
340     struct ata_device *atadev = device_get_softc(dev);
341
342     ATA_SETMODE(device_get_parent(dev), dev);
343
344     /* enable read caching */
345     ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_ENAB_RCACHE, 0, 0);
346
347     /* enable write caching if enabled */
348     if (ata_wc)
349         ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_ENAB_WCACHE, 0, 0);
350     else
351         ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_DIS_WCACHE, 0, 0);
352
353     /* use multiple sectors/interrupt if device supports it */
354     if (ad_version(atadev->param.version_major)) {
355         int secsperint = max(1, min(atadev->param.sectors_intr, 16));
356
357         if (!ata_controlcmd(dev, ATA_SET_MULTI, 0, 0, secsperint))
358             atadev->max_iosize = secsperint * DEV_BSIZE;
359     }
360     else
361         atadev->max_iosize = DEV_BSIZE;
362 }
363
364 void
365 ad_describe(device_t dev)
366 {
367     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
368     struct ata_device *atadev = device_get_softc(dev);
369     struct ad_softc *adp = device_get_ivars(dev);
370     u_int8_t *marker, vendor[64], product[64];
371
372     /* try to seperate the ATA model string into vendor and model parts */
373     if ((marker = index(atadev->param.model, ' ')) ||
374         (marker = index(atadev->param.model, '-'))) {
375         int len = (marker - atadev->param.model);
376
377         strncpy(vendor, atadev->param.model, len);
378         vendor[len++] = 0;
379         strcat(vendor, " ");
380         strncpy(product, atadev->param.model + len, 40 - len);
381         vendor[40 - len] = 0;
382     }
383     else {
384         if (!strncmp(atadev->param.model, "ST", 2))
385             strcpy(vendor, "Seagate ");
386         else
387             strcpy(vendor, "");
388         strncpy(product, atadev->param.model, 40);
389     }
390
391     device_printf(dev, "%lluMB <%s%s %.8s> at ata%d-%s %s%s\n",
392                   (unsigned long long)(adp->total_secs / (1048576 / DEV_BSIZE)),
393                   vendor, product, atadev->param.revision,
394                   device_get_unit(ch->dev),
395                   (atadev->unit == ATA_MASTER) ? "master" : "slave",
396                   (adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "",
397                   ata_mode2str(atadev->mode));
398     if (bootverbose) {
399         device_printf(dev, "%llu sectors [%lldC/%dH/%dS] "
400                       "%d sectors/interrupt %d depth queue\n",
401                       (unsigned long long)adp->total_secs,
402                       (unsigned long long)(adp->total_secs /
403                                            (adp->heads * adp->sectors)),
404                       adp->heads, adp->sectors, atadev->max_iosize / DEV_BSIZE,
405                       adp->num_tags + 1);
406     }
407 }
408
409 static int
410 ad_version(u_int16_t version)
411 {
412     int bit;
413
414     if (version == 0xffff)
415         return 0;
416     for (bit = 15; bit >= 0; bit--)
417         if (version & (1<<bit))
418             return bit;
419     return 0;
420 }
421
422 static device_method_t ad_methods[] = {
423     /* device interface */
424     DEVMETHOD(device_probe,     ad_probe),
425     DEVMETHOD(device_attach,    ad_attach),
426     DEVMETHOD(device_detach,    ad_detach),
427     DEVMETHOD(device_shutdown,  ad_shutdown),
428
429     /* ATA methods */
430     DEVMETHOD(ata_reinit,       ad_reinit),
431
432     { 0, 0 }
433 };
434
435 static driver_t ad_driver = {
436     "ad",
437     ad_methods,
438     0,
439 };
440
441 devclass_t ad_devclass;
442
443 DRIVER_MODULE(ad, ata, ad_driver, ad_devclass, NULL, NULL);
444 MODULE_VERSION(ad, 1);
445 MODULE_DEPEND(ad, ata, 1, 1, 1);