]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ata/ata-disk.c
This commit was generated by cvs2svn to compensate for changes in r147801,
[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, return error */
207     if (((atadev->unit == ATA_MASTER) && !(ch->devices & ATA_ATA_MASTER)) ||
208         ((atadev->unit == ATA_SLAVE) && !(ch->devices & ATA_ATA_SLAVE))) {
209         return 1;
210     }
211     ad_init(dev);
212     return 0;
213 }
214
215 static void 
216 ad_strategy(struct bio *bp)
217 {
218     device_t dev =  bp->bio_disk->d_drv1;
219     struct ata_device *atadev = device_get_softc(dev);
220     struct ata_request *request;
221
222     if (!(request = ata_alloc_request())) {
223         device_printf(dev, "FAILURE - out of memory in start\n");
224         biofinish(bp, NULL, ENOMEM);
225         return;
226     }
227
228     /* setup request */
229     request->dev = dev;
230     request->bio = bp;
231     request->callback = ad_done;
232     request->timeout = 5;
233     request->retries = 2;
234     request->data = bp->bio_data;
235     request->bytecount = bp->bio_bcount;
236     request->u.ata.lba = bp->bio_pblkno;
237     request->u.ata.count = request->bytecount / DEV_BSIZE;
238     request->transfersize = min(bp->bio_bcount, atadev->max_iosize);
239
240     switch (bp->bio_cmd) {
241     case BIO_READ:
242         request->flags = ATA_R_READ;
243         if (atadev->mode >= ATA_DMA) {
244             request->u.ata.command = ATA_READ_DMA;
245             request->flags |= ATA_R_DMA;
246         }
247         else if (atadev->max_iosize > DEV_BSIZE)
248             request->u.ata.command = ATA_READ_MUL;
249         else
250             request->u.ata.command = ATA_READ;
251         break;
252     case BIO_WRITE:
253         request->flags = ATA_R_WRITE;
254         if (atadev->mode >= ATA_DMA) {
255             request->u.ata.command = ATA_WRITE_DMA;
256             request->flags |= ATA_R_DMA;
257         }
258         else if (atadev->max_iosize > DEV_BSIZE)
259             request->u.ata.command = ATA_WRITE_MUL;
260         else
261             request->u.ata.command = ATA_WRITE;
262         break;
263     default:
264         device_printf(dev, "FAILURE - unknown BIO operation\n");
265         ata_free_request(request);
266         biofinish(bp, NULL, EIO);
267         return;
268     }
269     request->flags |= ATA_R_ORDERED;
270     ata_queue_request(request);
271 }
272
273 static void
274 ad_done(struct ata_request *request)
275 {
276     struct bio *bp = request->bio;
277
278     /* finish up transfer */
279     if ((bp->bio_error = request->result))
280         bp->bio_flags |= BIO_ERROR;
281     bp->bio_resid = bp->bio_bcount - request->donecount;
282     biodone(bp);
283     ata_free_request(request);
284 }
285
286 static int
287 ad_ioctl(struct disk *disk, u_long cmd, void *data, int flag, struct thread *td)
288 {
289     return ata_device_ioctl(disk->d_drv1, cmd, data);
290 }
291
292 static int
293 ad_dump(void *arg, void *virtual, vm_offset_t physical,
294        off_t offset, size_t length)
295 {
296     struct disk *dp = arg;
297     device_t dev = dp->d_drv1;
298     struct ata_device *atadev = device_get_softc(dev);
299     struct ad_softc *adp = device_get_ivars(dev);
300     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
301     struct ata_request request;
302
303     if (!adp)
304         return ENXIO;
305
306     bzero(&request, sizeof(struct ata_request));
307     request.dev = dev;
308
309     if (length) {
310         request.data = virtual;
311         request.bytecount = length;
312         request.transfersize = min(length, atadev->max_iosize);
313         request.flags = ATA_R_WRITE;
314         if (atadev->max_iosize > DEV_BSIZE)
315             request.u.ata.command = ATA_WRITE_MUL;
316         else
317             request.u.ata.command = ATA_WRITE;
318         request.u.ata.lba = offset / DEV_BSIZE;
319         request.u.ata.count = request.bytecount / DEV_BSIZE;
320     }
321     else {
322         request.u.ata.command = ATA_FLUSHCACHE;
323         request.flags = ATA_R_CONTROL;
324     }
325     if (ch->hw.begin_transaction(&request) == ATA_OP_CONTINUES) {
326         do {
327             DELAY(20);
328         } while (ch->hw.end_transaction(&request) == ATA_OP_CONTINUES);
329     }
330     if (request.status & ATA_S_ERROR)
331         return EIO;
332     return 0;
333 }
334
335 static void
336 ad_init(device_t dev)
337 {
338     struct ata_device *atadev = device_get_softc(dev);
339
340     ATA_SETMODE(device_get_parent(dev), dev);
341
342     /* enable readahead caching */
343     if (atadev->param.support.command1 & ATA_SUPPORT_LOOKAHEAD)
344         ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_ENAB_RCACHE, 0, 0);
345
346     /* enable write caching if supported and configured */
347     if (atadev->param.support.command1 & ATA_SUPPORT_WRITECACHE) {
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
354     /* use multiple sectors/interrupt if device supports it */
355     if (ad_version(atadev->param.version_major)) {
356         int secsperint = max(1, min(atadev->param.sectors_intr, 16));
357
358         if (!ata_controlcmd(dev, ATA_SET_MULTI, 0, 0, secsperint))
359             atadev->max_iosize = secsperint * DEV_BSIZE;
360     }
361     else
362         atadev->max_iosize = DEV_BSIZE;
363 }
364
365 void
366 ad_describe(device_t dev)
367 {
368     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
369     struct ata_device *atadev = device_get_softc(dev);
370     struct ad_softc *adp = device_get_ivars(dev);
371     u_int8_t *marker, vendor[64], product[64];
372
373     /* try to seperate the ATA model string into vendor and model parts */
374     if ((marker = index(atadev->param.model, ' ')) ||
375         (marker = index(atadev->param.model, '-'))) {
376         int len = (marker - atadev->param.model);
377
378         strncpy(vendor, atadev->param.model, len);
379         vendor[len++] = 0;
380         strcat(vendor, " ");
381         strncpy(product, atadev->param.model + len, 40 - len);
382         vendor[40 - len] = 0;
383     }
384     else {
385         if (!strncmp(atadev->param.model, "ST", 2))
386             strcpy(vendor, "Seagate ");
387         else
388             strcpy(vendor, "");
389         strncpy(product, atadev->param.model, 40);
390     }
391
392     device_printf(dev, "%lluMB <%s%s %.8s> at ata%d-%s %s%s\n",
393                   (unsigned long long)(adp->total_secs / (1048576 / DEV_BSIZE)),
394                   vendor, product, atadev->param.revision,
395                   device_get_unit(ch->dev),
396                   (atadev->unit == ATA_MASTER) ? "master" : "slave",
397                   (adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "",
398                   ata_mode2str(atadev->mode));
399     if (bootverbose) {
400         device_printf(dev, "%llu sectors [%lldC/%dH/%dS] "
401                       "%d sectors/interrupt %d depth queue\n",
402                       (unsigned long long)adp->total_secs,
403                       (unsigned long long)(adp->total_secs /
404                                            (adp->heads * adp->sectors)),
405                       adp->heads, adp->sectors, atadev->max_iosize / DEV_BSIZE,
406                       adp->num_tags + 1);
407     }
408 }
409
410 static int
411 ad_version(u_int16_t version)
412 {
413     int bit;
414
415     if (version == 0xffff)
416         return 0;
417     for (bit = 15; bit >= 0; bit--)
418         if (version & (1<<bit))
419             return bit;
420     return 0;
421 }
422
423 static device_method_t ad_methods[] = {
424     /* device interface */
425     DEVMETHOD(device_probe,     ad_probe),
426     DEVMETHOD(device_attach,    ad_attach),
427     DEVMETHOD(device_detach,    ad_detach),
428     DEVMETHOD(device_shutdown,  ad_shutdown),
429
430     /* ATA methods */
431     DEVMETHOD(ata_reinit,       ad_reinit),
432
433     { 0, 0 }
434 };
435
436 static driver_t ad_driver = {
437     "ad",
438     ad_methods,
439     0,
440 };
441
442 devclass_t ad_devclass;
443
444 DRIVER_MODULE(ad, ata, ad_driver, ad_devclass, NULL, NULL);
445 MODULE_VERSION(ad, 1);
446 MODULE_DEPEND(ad, ata, 1, 1, 1);