aac_disk.c (93495) | aac_disk.c (95350) |
---|---|
1/*- 2 * Copyright (c) 2000 Michael Smith 3 * Copyright (c) 2001 Scott Long 4 * Copyright (c) 2000 BSDi 5 * Copyright (c) 2001 Adaptec, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 12 unchanged lines hidden (view full) --- 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * | 1/*- 2 * Copyright (c) 2000 Michael Smith 3 * Copyright (c) 2001 Scott Long 4 * Copyright (c) 2000 BSDi 5 * Copyright (c) 2001 Adaptec, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 12 unchanged lines hidden (view full) --- 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * |
29 * $FreeBSD: head/sys/dev/aac/aac_disk.c 93495 2002-03-31 22:29:52Z phk $ | 29 * $FreeBSD: head/sys/dev/aac/aac_disk.c 95350 2002-04-24 05:12:50Z scottl $ |
30 */ 31 32#include "opt_aac.h" 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#include <sys/sysctl.h> --- 65 unchanged lines hidden (view full) --- 103}; 104 105static driver_t aac_disk_driver = { 106 "aacd", 107 aac_disk_methods, 108 sizeof(struct aac_disk) 109}; 110 | 30 */ 31 32#include "opt_aac.h" 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#include <sys/sysctl.h> --- 65 unchanged lines hidden (view full) --- 103}; 104 105static driver_t aac_disk_driver = { 106 "aacd", 107 aac_disk_methods, 108 sizeof(struct aac_disk) 109}; 110 |
111#define AAC_MAXIO 65536 112 |
|
111DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0); 112 113/* sysctl tunables */ | 113DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0); 114 115/* sysctl tunables */ |
114static unsigned int aac_iosize_max = 65536; /* due to limits of the card */ | 116static unsigned int aac_iosize_max = AAC_MAXIO; /* due to limits of the card */ |
115TUNABLE_INT("hw.aac.iosize_max", &aac_iosize_max); 116 117SYSCTL_DECL(_hw_aac); 118SYSCTL_UINT(_hw_aac, OID_AUTO, iosize_max, CTLFLAG_RD, &aac_iosize_max, 0, 119 "Max I/O size per transfer to an array"); 120 | 117TUNABLE_INT("hw.aac.iosize_max", &aac_iosize_max); 118 119SYSCTL_DECL(_hw_aac); 120SYSCTL_UINT(_hw_aac, OID_AUTO, iosize_max, CTLFLAG_RD, &aac_iosize_max, 0, 121 "Max I/O size per transfer to an array"); 122 |
121#define AAC_MAXIO 65536 122 | |
123/* 124 * Handle open from generic layer. 125 * 126 * This is called by the diskslice code on first open in order to get the 127 * basic device geometry paramters. 128 */ 129static int 130aac_disk_open(dev_t dev, int flags, int fmt, d_thread_t *td) --- 77 unchanged lines hidden (view full) --- 208 devstat_start_transaction(&sc->ad_stats); 209 210 /* pass the bio to the controller - it can work out who we are */ 211 aac_submit_bio(bp); 212 return; 213} 214 215/* | 123/* 124 * Handle open from generic layer. 125 * 126 * This is called by the diskslice code on first open in order to get the 127 * basic device geometry paramters. 128 */ 129static int 130aac_disk_open(dev_t dev, int flags, int fmt, d_thread_t *td) --- 77 unchanged lines hidden (view full) --- 208 devstat_start_transaction(&sc->ad_stats); 209 210 /* pass the bio to the controller - it can work out who we are */ 211 aac_submit_bio(bp); 212 return; 213} 214 215/* |
216 * Map the S/G elements for doing a dump. 217 */ 218static void 219aac_dump_map_sg(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 220{ 221 struct aac_fib *fib; 222 struct aac_blockwrite *bw; 223 struct aac_sg_table *sg; 224 int i; 225 226 fib = (struct aac_fib *)arg; 227 bw = (struct aac_blockwrite *)&fib->data[0]; 228 sg = &bw->SgMap; 229 230 if (sg != NULL) { 231 sg->SgCount = nsegs; 232 for (i = 0; i < nsegs; i++) { 233 sg->SgEntry[i].SgAddress = segs[i].ds_addr; 234 sg->SgEntry[i].SgByteCount = segs[i].ds_len; 235 } 236 fib->Header.Size = nsegs * sizeof(struct aac_sg_entry); 237 } 238} 239 240/* |
|
216 * Dump memory out to an array 217 * | 241 * Dump memory out to an array 242 * |
218 * This queues blocks of memory of size AAC_MAXIO to the controller and waits 219 * for the controller to complete the requests. | 243 * Send out one command at a time with up to AAC_MAXIO of data. |
220 */ 221static int 222aac_disk_dump(dev_t dev, void *virtual, vm_offset_t physical, off_t offset, size_t length) 223{ | 244 */ 245static int 246aac_disk_dump(dev_t dev, void *virtual, vm_offset_t physical, off_t offset, size_t length) 247{ |
224 225 /* XXX: This needs modified for the new dump API */ 226 return (ENXIO); 227#if 0 | |
228 struct aac_disk *ad; 229 struct aac_softc *sc; | 248 struct aac_disk *ad; 249 struct aac_softc *sc; |
230 vm_offset_t addr; 231 long blkcnt; 232 unsigned int count, blkno, secsize; 233 int dumppages; 234 int i, error; | 250 struct aac_fib *fib; 251 struct aac_blockwrite *bw; 252 size_t len; 253 int size; 254 static bus_dmamap_t dump_datamap; 255 static int first = 0; |
235 236 ad = dev->si_drv1; | 256 257 ad = dev->si_drv1; |
237 addr = 0; 238 dumppages = AAC_MAXIO / PAGE_SIZE; | |
239 | 258 |
240 if ((error = disk_dumpcheck(dev, &count, &blkno, &secsize))) 241 return (error); 242 | |
243 if (ad == NULL) | 259 if (ad == NULL) |
244 return (ENXIO); | 260 return (EINVAL); |
245 246 sc= ad->ad_controller; 247 | 261 262 sc= ad->ad_controller; 263 |
248 blkcnt = howmany(PAGE_SIZE, secsize); 249 250 while (count > 0) { 251 caddr_t va = NULL; 252 253 if ((count / blkcnt) < dumppages) 254 dumppages = count / blkcnt; 255 256 for (i = 0; i < dumppages; ++i) { 257 vm_offset_t a = addr + (i * PAGE_SIZE); 258 if (is_physical_memory(a)) { 259 va = pmap_kenter_temporary(trunc_page(a), i); 260 } else { 261 va = pmap_kenter_temporary(trunc_page(0), i); 262 } | 264 if (!first) { 265 first = 1; 266 if (bus_dmamap_create(sc->aac_buffer_dmat, 0, &dump_datamap)) { 267 printf("bus_dmamap_create failed\n"); 268 return (ENOMEM); |
263 } | 269 } |
270 } |
|
264 | 271 |
265retry: 266 /* 267 * Queue the block to the controller. If the queue is full, 268 * EBUSY will be returned. 269 */ 270 error = aac_dump_enqueue(ad, blkno, va, dumppages); 271 if (error && (error != EBUSY)) 272 return (error); | 272 aac_get_sync_fib(sc, &fib, AAC_SYNC_LOCK_FORCE); 273 bw = (struct aac_blockwrite *)&fib->data[0]; |
273 | 274 |
274 if (!error) { 275 if (dumpstatus(addr, (off_t)(count * DEV_BSIZE)) < 0) 276 return (EINTR); | 275 while (length > 0) { 276 len = (length > AAC_MAXIO) ? AAC_MAXIO : length; 277 bw->Command = VM_CtBlockWrite; 278 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId; 279 bw->BlockNumber = offset / AAC_BLOCK_SIZE; 280 bw->ByteCount = len; 281 bw->Stable = CUNSTABLE; 282 bus_dmamap_load(sc->aac_buffer_dmat, dump_datamap, virtual, 283 len, aac_dump_map_sg, fib, 0); 284 bus_dmamap_sync(sc->aac_buffer_dmat, dump_datamap, 285 BUS_DMASYNC_PREWRITE); |
277 | 286 |
278 blkno += blkcnt * dumppages; 279 count -= blkcnt * dumppages; 280 addr += PAGE_SIZE * dumppages; 281 if (count > 0) 282 continue; 283 } | 287 /* fib->Header.Size is set in aac_dump_map_sg */ 288 size = fib->Header.Size + sizeof(struct aac_blockwrite); |
284 | 289 |
285 /* 286 * Either the queue was full on the last attemp, or we have no 287 * more data to dump. Let the queue drain out and retry the 288 * block if the queue was full. 289 */ 290 aac_dump_complete(sc); 291 292 if (error == EBUSY) 293 goto retry; | 290 if (aac_sync_fib(sc, ContainerCommand, 0, fib, size)) { 291 printf("Error dumping block 0x%x\n", physical); 292 return (EIO); 293 } 294 length -= len; 295 offset += len; |
294 } 295 296 return (0); | 296 } 297 298 return (0); |
297#endif | |
298} 299 300/* 301 * Handle completion of an I/O request. 302 */ 303void 304aac_biodone(struct bio *bp) 305{ --- 113 unchanged lines hidden --- | 299} 300 301/* 302 * Handle completion of an I/O request. 303 */ 304void 305aac_biodone(struct bio *bp) 306{ --- 113 unchanged lines hidden --- |