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 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 |
111#define AAC_MAXIO 65536 112 |
113DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0); 114 115/* sysctl tunables */ |
116static unsigned int aac_iosize_max = AAC_MAXIO; /* due to limits of the card */ |
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 |
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/* |
241 * Dump memory out to an array 242 * |
243 * Send out one command at a time with up to AAC_MAXIO of data. |
244 */ 245static int 246aac_disk_dump(dev_t dev, void *virtual, vm_offset_t physical, off_t offset, size_t length) 247{ |
248 struct aac_disk *ad; 249 struct aac_softc *sc; |
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; |
256 257 ad = dev->si_drv1; |
258 |
259 if (ad == NULL) |
260 return (EINVAL); |
261 262 sc= ad->ad_controller; 263 |
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); |
269 } |
270 } |
271 |
272 aac_get_sync_fib(sc, &fib, AAC_SYNC_LOCK_FORCE); 273 bw = (struct aac_blockwrite *)&fib->data[0]; |
274 |
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); |
286 |
287 /* fib->Header.Size is set in aac_dump_map_sg */ 288 size = fib->Header.Size + sizeof(struct aac_blockwrite); |
289 |
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; |
296 } 297 298 return (0); |
299} 300 301/* 302 * Handle completion of an I/O request. 303 */ 304void 305aac_biodone(struct bio *bp) 306{ --- 113 unchanged lines hidden --- |