161 * Private seg op routines.
162 */
163 static int segdev_dup(struct seg *, struct seg *);
164 static int segdev_unmap(struct seg *, caddr_t, size_t);
165 static void segdev_free(struct seg *);
166 static faultcode_t segdev_fault(struct hat *, struct seg *, caddr_t, size_t,
167 enum fault_type, enum seg_rw);
168 static faultcode_t segdev_faulta(struct seg *, caddr_t);
169 static int segdev_setprot(struct seg *, caddr_t, size_t, uint_t);
170 static int segdev_checkprot(struct seg *, caddr_t, size_t, uint_t);
171 static void segdev_badop(void);
172 static int segdev_sync(struct seg *, caddr_t, size_t, int, uint_t);
173 static size_t segdev_incore(struct seg *, caddr_t, size_t, char *);
174 static int segdev_lockop(struct seg *, caddr_t, size_t, int, int,
175 ulong_t *, size_t);
176 static int segdev_getprot(struct seg *, caddr_t, size_t, uint_t *);
177 static u_offset_t segdev_getoffset(struct seg *, caddr_t);
178 static int segdev_gettype(struct seg *, caddr_t);
179 static int segdev_getvp(struct seg *, caddr_t, struct vnode **);
180 static int segdev_advise(struct seg *, caddr_t, size_t, uint_t);
181 static void segdev_dump(struct seg *);
182 static int segdev_pagelock(struct seg *, caddr_t, size_t,
183 struct page ***, enum lock_type, enum seg_rw);
184 static int segdev_getmemid(struct seg *, caddr_t, memid_t *);
185
186 /*
187 * XXX this struct is used by rootnex_map_fault to identify
188 * the segment it has been passed. So if you make it
189 * "static" you'll need to fix rootnex_map_fault.
190 */
191 struct seg_ops segdev_ops = {
192 .dup = segdev_dup,
193 .unmap = segdev_unmap,
194 .free = segdev_free,
195 .fault = segdev_fault,
196 .faulta = segdev_faulta,
197 .setprot = segdev_setprot,
198 .checkprot = segdev_checkprot,
199 .kluster = (int (*)())segdev_badop,
200 .sync = segdev_sync,
201 .incore = segdev_incore,
202 .lockop = segdev_lockop,
203 .getprot = segdev_getprot,
204 .getoffset = segdev_getoffset,
205 .gettype = segdev_gettype,
206 .getvp = segdev_getvp,
207 .advise = segdev_advise,
208 .dump = segdev_dump,
209 .pagelock = segdev_pagelock,
210 .getmemid = segdev_getmemid,
211 };
212
213 /*
214 * Private segdev support routines
215 */
216 static struct segdev_data *sdp_alloc(void);
217
218 static void segdev_softunlock(struct hat *, struct seg *, caddr_t,
219 size_t, enum seg_rw);
220
221 static faultcode_t segdev_faultpage(struct hat *, struct seg *, caddr_t,
222 struct vpage *, enum fault_type, enum seg_rw, devmap_handle_t *);
223
224 static faultcode_t segdev_faultpages(struct hat *, struct seg *, caddr_t,
225 size_t, enum fault_type, enum seg_rw, devmap_handle_t *);
226
227 static struct devmap_ctx *devmap_ctxinit(dev_t, ulong_t);
228 static struct devmap_softlock *devmap_softlock_init(dev_t, ulong_t);
2354
2355 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as, &seg->s_as->a_lock));
2356
2357 return (0);
2358 }
2359
2360 /*
2361 * segdev pages are not in the cache, and thus can't really be controlled.
2362 * Hence, advise is simply always successful.
2363 */
2364 /*ARGSUSED*/
2365 static int
2366 segdev_advise(struct seg *seg, caddr_t addr, size_t len, uint_t behav)
2367 {
2368 TRACE_0(TR_FAC_DEVMAP, TR_DEVMAP_ADVISE, "segdev_advise:start");
2369
2370 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as, &seg->s_as->a_lock));
2371
2372 return (0);
2373 }
2374
2375 /*
2376 * segdev pages are not dumped, so we just return
2377 */
2378 /*ARGSUSED*/
2379 static void
2380 segdev_dump(struct seg *seg)
2381 {}
2382
2383 /*
2384 * ddi_segmap_setup: Used by drivers who wish specify mapping attributes
2385 * for a segment. Called from a drivers segmap(9E)
2386 * routine.
2387 */
2388 /*ARGSUSED*/
2389 int
2390 ddi_segmap_setup(dev_t dev, off_t offset, struct as *as, caddr_t *addrp,
2391 off_t len, uint_t prot, uint_t maxprot, uint_t flags, cred_t *cred,
2392 ddi_device_acc_attr_t *accattrp, uint_t rnumber)
2393 {
2394 struct segdev_crargs dev_a;
2395 int (*mapfunc)(dev_t dev, off_t off, int prot);
2396 uint_t hat_attr;
2397 pfn_t pfn;
2398 int error, i;
2399
2400 TRACE_0(TR_FAC_DEVMAP, TR_DEVMAP_SEGMAP_SETUP,
2401 "ddi_segmap_setup:start");
|
161 * Private seg op routines.
162 */
163 static int segdev_dup(struct seg *, struct seg *);
164 static int segdev_unmap(struct seg *, caddr_t, size_t);
165 static void segdev_free(struct seg *);
166 static faultcode_t segdev_fault(struct hat *, struct seg *, caddr_t, size_t,
167 enum fault_type, enum seg_rw);
168 static faultcode_t segdev_faulta(struct seg *, caddr_t);
169 static int segdev_setprot(struct seg *, caddr_t, size_t, uint_t);
170 static int segdev_checkprot(struct seg *, caddr_t, size_t, uint_t);
171 static void segdev_badop(void);
172 static int segdev_sync(struct seg *, caddr_t, size_t, int, uint_t);
173 static size_t segdev_incore(struct seg *, caddr_t, size_t, char *);
174 static int segdev_lockop(struct seg *, caddr_t, size_t, int, int,
175 ulong_t *, size_t);
176 static int segdev_getprot(struct seg *, caddr_t, size_t, uint_t *);
177 static u_offset_t segdev_getoffset(struct seg *, caddr_t);
178 static int segdev_gettype(struct seg *, caddr_t);
179 static int segdev_getvp(struct seg *, caddr_t, struct vnode **);
180 static int segdev_advise(struct seg *, caddr_t, size_t, uint_t);
181 static int segdev_pagelock(struct seg *, caddr_t, size_t,
182 struct page ***, enum lock_type, enum seg_rw);
183 static int segdev_getmemid(struct seg *, caddr_t, memid_t *);
184
185 /*
186 * XXX this struct is used by rootnex_map_fault to identify
187 * the segment it has been passed. So if you make it
188 * "static" you'll need to fix rootnex_map_fault.
189 */
190 struct seg_ops segdev_ops = {
191 .dup = segdev_dup,
192 .unmap = segdev_unmap,
193 .free = segdev_free,
194 .fault = segdev_fault,
195 .faulta = segdev_faulta,
196 .setprot = segdev_setprot,
197 .checkprot = segdev_checkprot,
198 .kluster = (int (*)())segdev_badop,
199 .sync = segdev_sync,
200 .incore = segdev_incore,
201 .lockop = segdev_lockop,
202 .getprot = segdev_getprot,
203 .getoffset = segdev_getoffset,
204 .gettype = segdev_gettype,
205 .getvp = segdev_getvp,
206 .advise = segdev_advise,
207 .pagelock = segdev_pagelock,
208 .getmemid = segdev_getmemid,
209 };
210
211 /*
212 * Private segdev support routines
213 */
214 static struct segdev_data *sdp_alloc(void);
215
216 static void segdev_softunlock(struct hat *, struct seg *, caddr_t,
217 size_t, enum seg_rw);
218
219 static faultcode_t segdev_faultpage(struct hat *, struct seg *, caddr_t,
220 struct vpage *, enum fault_type, enum seg_rw, devmap_handle_t *);
221
222 static faultcode_t segdev_faultpages(struct hat *, struct seg *, caddr_t,
223 size_t, enum fault_type, enum seg_rw, devmap_handle_t *);
224
225 static struct devmap_ctx *devmap_ctxinit(dev_t, ulong_t);
226 static struct devmap_softlock *devmap_softlock_init(dev_t, ulong_t);
2352
2353 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as, &seg->s_as->a_lock));
2354
2355 return (0);
2356 }
2357
2358 /*
2359 * segdev pages are not in the cache, and thus can't really be controlled.
2360 * Hence, advise is simply always successful.
2361 */
2362 /*ARGSUSED*/
2363 static int
2364 segdev_advise(struct seg *seg, caddr_t addr, size_t len, uint_t behav)
2365 {
2366 TRACE_0(TR_FAC_DEVMAP, TR_DEVMAP_ADVISE, "segdev_advise:start");
2367
2368 ASSERT(seg->s_as && AS_LOCK_HELD(seg->s_as, &seg->s_as->a_lock));
2369
2370 return (0);
2371 }
2372
2373 /*
2374 * ddi_segmap_setup: Used by drivers who wish specify mapping attributes
2375 * for a segment. Called from a drivers segmap(9E)
2376 * routine.
2377 */
2378 /*ARGSUSED*/
2379 int
2380 ddi_segmap_setup(dev_t dev, off_t offset, struct as *as, caddr_t *addrp,
2381 off_t len, uint_t prot, uint_t maxprot, uint_t flags, cred_t *cred,
2382 ddi_device_acc_attr_t *accattrp, uint_t rnumber)
2383 {
2384 struct segdev_crargs dev_a;
2385 int (*mapfunc)(dev_t dev, off_t off, int prot);
2386 uint_t hat_attr;
2387 pfn_t pfn;
2388 int error, i;
2389
2390 TRACE_0(TR_FAC_DEVMAP, TR_DEVMAP_SEGMAP_SETUP,
2391 "ddi_segmap_setup:start");
|