36 #include <sys/dktp/fctypes.h>
37 #include <sys/dktp/flowctrl.h>
38 #include <sys/param.h>
39 #include <vm/page.h>
40 #include <sys/modctl.h>
41
42 /*
43 * Object Management
44 */
45
46 static struct buf *qmerge_nextbp(struct que_data *qfp, struct buf *bp_merge,
47 int *can_merge);
48
49 static struct modlmisc modlmisc = {
50 &mod_miscops, /* Type of module */
51 "Device Strategy Objects"
52 };
53
54 static struct modlinkage modlinkage = {
55 MODREV_1,
56 &modlmisc,
57 NULL
58 };
59
60 int
61 _init(void)
62 {
63 return (mod_install(&modlinkage));
64 }
65
66 int
67 _fini(void)
68 {
69 return (mod_remove(&modlinkage));
70 }
71
72 int
73 _info(struct modinfo *modinfop)
74 {
75 return (mod_info(&modlinkage, modinfop));
76 }
77
184
185
186 /*
187 * Single Command per Device
188 */
189 /*
190 * Local Function Prototypes
191 */
192 static int dsngl_restart();
193
194 static int dsngl_enque(opaque_t, struct buf *);
195 static int dsngl_deque(opaque_t, struct buf *);
196
197 struct flc_objops dsngl_ops = {
198 fc_init,
199 fc_free,
200 dsngl_enque,
201 dsngl_deque,
202 fc_start_kstat,
203 fc_stop_kstat,
204 0, 0
205 };
206
207 struct flc_obj *
208 dsngl_create()
209 {
210 return (fc_create((struct flc_objops *)&dsngl_ops));
211 }
212
213 static int
214 dsngl_enque(opaque_t queuep, struct buf *in_bp)
215 {
216 struct fc_data *dsnglp = (struct fc_data *)queuep;
217 opaque_t tgcom_objp;
218 opaque_t que_objp;
219
220 que_objp = dsnglp->ds_queobjp;
221 tgcom_objp = dsnglp->ds_tgcomobjp;
222
223 if (!in_bp)
224 return (0);
309
310
311 /*
312 * Multiple Commands per Device
313 */
314 /*
315 * Local Function Prototypes
316 */
317 static int dmult_restart();
318
319 static int dmult_enque(opaque_t, struct buf *);
320 static int dmult_deque(opaque_t, struct buf *);
321
322 struct flc_objops dmult_ops = {
323 fc_init,
324 fc_free,
325 dmult_enque,
326 dmult_deque,
327 fc_start_kstat,
328 fc_stop_kstat,
329 0, 0
330 };
331
332 struct flc_obj *
333 dmult_create()
334 {
335 return (fc_create((struct flc_objops *)&dmult_ops));
336
337 }
338
339
340 /*
341 * Some of the object management functions QUE_ADD() and QUE_DEL()
342 * do not accquire lock.
343 * They depend on dmult_enque(), dmult_deque() to do all locking.
344 * If this changes we have to grab locks in qmerge_add() and qmerge_del().
345 */
346 static int
347 dmult_enque(opaque_t queuep, struct buf *in_bp)
348 {
349 struct fc_data *dmultp = (struct fc_data *)queuep;
456 * Duplexed Commands per Device: Read Queue and Write Queue
457 */
458 /*
459 * Local Function Prototypes
460 */
461 static int duplx_restart();
462
463 static int duplx_init(opaque_t queuep, opaque_t tgcom_objp, opaque_t que_objp,
464 void *lkarg);
465 static int duplx_free(struct flc_obj *flcobjp);
466 static int duplx_enque(opaque_t queuep, struct buf *bp);
467 static int duplx_deque(opaque_t queuep, struct buf *bp);
468
469 struct flc_objops duplx_ops = {
470 duplx_init,
471 duplx_free,
472 duplx_enque,
473 duplx_deque,
474 fc_start_kstat,
475 fc_stop_kstat,
476 0, 0
477 };
478
479 struct flc_obj *
480 duplx_create()
481 {
482 struct flc_obj *flcobjp;
483 struct duplx_data *fcdp;
484
485 flcobjp = kmem_zalloc((sizeof (*flcobjp) + sizeof (*fcdp)), KM_NOSLEEP);
486 if (!flcobjp)
487 return (NULL);
488
489 fcdp = (struct duplx_data *)(flcobjp+1);
490 flcobjp->flc_data = (opaque_t)fcdp;
491 flcobjp->flc_ops = &duplx_ops;
492
493 fcdp->ds_writeq.fc_qobjp = qfifo_create();
494 if (!(fcdp->ds_writeq.fc_qobjp = qfifo_create())) {
495 kmem_free(flcobjp, (sizeof (*flcobjp) + sizeof (*fcdp)));
496 return (NULL);
680 duplx_restart(struct duplx_data *duplxp)
681 {
682 (void) duplx_enque(duplxp, NULL);
683 return (-1);
684 }
685
686 /*
687 * Tagged queueing flow control
688 */
689 /*
690 * Local Function Prototypes
691 */
692
693 struct flc_objops adapt_ops = {
694 fc_init,
695 fc_free,
696 dmult_enque,
697 dmult_deque,
698 fc_start_kstat,
699 fc_stop_kstat,
700 0, 0
701 };
702
703 struct flc_obj *
704 adapt_create()
705 {
706 return (fc_create((struct flc_objops *)&adapt_ops));
707
708 }
709
710 /*
711 * Common Queue functions
712 */
713
714 /*
715 * Local static data
716 */
717 #ifdef Q_DEBUG
718 #define DENT 0x0001
719 #define DERR 0x0002
720 #define DIO 0x0004
776 qfp->q_tab.b_actl = NULL;
777 bp->av_forw = 0;
778 }
779 return (bp);
780 }
781
782
783
784 /*
785 * Qmerge
786 * Local Function Prototypes
787 */
788 static int qmerge_add(), qmerge_free();
789 static struct buf *qmerge_del(struct que_data *qfp);
790
791 struct que_objops qmerge_ops = {
792 que_init,
793 qmerge_free,
794 qmerge_add,
795 qmerge_del,
796 0, 0
797 };
798
799 /* fields in diskhd */
800 #define hd_cnt b_back
801 #define hd_private b_forw
802 #define hd_flags b_flags
803 #define hd_sync_next av_forw
804 #define hd_async_next av_back
805
806 #define hd_sync2async sync_async_ratio
807
808 #define QNEAR_FORWARD 0x01
809 #define QNEAR_BACKWARD 0x02
810 #define QNEAR_ASYNCONLY 0x04
811 #define QNEAR_ASYNCALSO 0x08
812
813 #define DBLK(bp) ((unsigned long)(bp)->b_private)
814
815 #define BP_LT_BP(a, b) (DBLK(a) < DBLK(b))
816 #define BP_GT_BP(a, b) (DBLK(a) > DBLK(b))
1317 }
1318 qmerge_mergesetup(bp_merge, next_bp);
1319 }
1320 return (bp_merge);
1321 }
1322
1323
1324 /*
1325 * FIFO Queue functions
1326 */
1327 /*
1328 * Local Function Prototypes
1329 */
1330 static int qfifo_add();
1331
1332 struct que_objops qfifo_ops = {
1333 que_init,
1334 que_free,
1335 qfifo_add,
1336 que_del,
1337 0, 0
1338 };
1339
1340 /*
1341 * Local static data
1342 */
1343 struct que_obj *
1344 qfifo_create()
1345 {
1346 return (que_create((struct que_objops *)&qfifo_ops));
1347 }
1348
1349 static int
1350 qfifo_add(struct que_data *qfp, struct buf *bp)
1351 {
1352
1353 if (!qfp->q_tab.b_actf)
1354 qfp->q_tab.b_actf = bp;
1355 else
1356 qfp->q_tab.b_actl->av_forw = bp;
1357 qfp->q_tab.b_actl = bp;
1358 bp->av_forw = NULL;
1359 return (0);
1360 }
1361
1362 /*
1363 * One-Way-Scan Queue functions
1364 */
1365 /*
1366 * Local Function Prototypes
1367 */
1368 static int qsort_add();
1369 static struct buf *qsort_del();
1370 static void oneway_scan_binary(struct diskhd *dp, struct buf *bp);
1371
1372 struct que_objops qsort_ops = {
1373 que_init,
1374 que_free,
1375 qsort_add,
1376 qsort_del,
1377 0, 0
1378 };
1379
1380 /*
1381 * Local static data
1382 */
1383 struct que_obj *
1384 qsort_create()
1385 {
1386 return (que_create((struct que_objops *)&qsort_ops));
1387 }
1388
1389 static int
1390 qsort_add(struct que_data *qfp, struct buf *bp)
1391 {
1392 qfp->q_cnt++;
1393 oneway_scan_binary(&qfp->q_tab, bp);
1394 return (0);
1395 }
1396
1397
1439 bp->av_forw = 0;
1440 if (!qfp->q_tab.b_actf && qfp->q_tab.b_pasf) {
1441 qfp->q_tab.b_actf = qfp->q_tab.b_pasf;
1442 qfp->q_tab.b_pasf = NULL;
1443 }
1444 return (bp);
1445 }
1446
1447 /*
1448 * Tagged queueing
1449 */
1450 /*
1451 * Local Function Prototypes
1452 */
1453
1454 struct que_objops qtag_ops = {
1455 que_init,
1456 que_free,
1457 qsort_add,
1458 qsort_del,
1459 0, 0
1460 };
1461
1462 /*
1463 * Local static data
1464 */
1465 struct que_obj *
1466 qtag_create()
1467 {
1468 return (que_create((struct que_objops *)&qtag_ops));
1469 }
|
36 #include <sys/dktp/fctypes.h>
37 #include <sys/dktp/flowctrl.h>
38 #include <sys/param.h>
39 #include <vm/page.h>
40 #include <sys/modctl.h>
41
42 /*
43 * Object Management
44 */
45
46 static struct buf *qmerge_nextbp(struct que_data *qfp, struct buf *bp_merge,
47 int *can_merge);
48
49 static struct modlmisc modlmisc = {
50 &mod_miscops, /* Type of module */
51 "Device Strategy Objects"
52 };
53
54 static struct modlinkage modlinkage = {
55 MODREV_1,
56 { &modlmisc, NULL }
57 };
58
59 int
60 _init(void)
61 {
62 return (mod_install(&modlinkage));
63 }
64
65 int
66 _fini(void)
67 {
68 return (mod_remove(&modlinkage));
69 }
70
71 int
72 _info(struct modinfo *modinfop)
73 {
74 return (mod_info(&modlinkage, modinfop));
75 }
76
183
184
185 /*
186 * Single Command per Device
187 */
188 /*
189 * Local Function Prototypes
190 */
191 static int dsngl_restart();
192
193 static int dsngl_enque(opaque_t, struct buf *);
194 static int dsngl_deque(opaque_t, struct buf *);
195
196 struct flc_objops dsngl_ops = {
197 fc_init,
198 fc_free,
199 dsngl_enque,
200 dsngl_deque,
201 fc_start_kstat,
202 fc_stop_kstat,
203 { NULL, NULL }
204 };
205
206 struct flc_obj *
207 dsngl_create()
208 {
209 return (fc_create((struct flc_objops *)&dsngl_ops));
210 }
211
212 static int
213 dsngl_enque(opaque_t queuep, struct buf *in_bp)
214 {
215 struct fc_data *dsnglp = (struct fc_data *)queuep;
216 opaque_t tgcom_objp;
217 opaque_t que_objp;
218
219 que_objp = dsnglp->ds_queobjp;
220 tgcom_objp = dsnglp->ds_tgcomobjp;
221
222 if (!in_bp)
223 return (0);
308
309
310 /*
311 * Multiple Commands per Device
312 */
313 /*
314 * Local Function Prototypes
315 */
316 static int dmult_restart();
317
318 static int dmult_enque(opaque_t, struct buf *);
319 static int dmult_deque(opaque_t, struct buf *);
320
321 struct flc_objops dmult_ops = {
322 fc_init,
323 fc_free,
324 dmult_enque,
325 dmult_deque,
326 fc_start_kstat,
327 fc_stop_kstat,
328 { NULL, NULL }
329 };
330
331 struct flc_obj *
332 dmult_create()
333 {
334 return (fc_create((struct flc_objops *)&dmult_ops));
335
336 }
337
338
339 /*
340 * Some of the object management functions QUE_ADD() and QUE_DEL()
341 * do not accquire lock.
342 * They depend on dmult_enque(), dmult_deque() to do all locking.
343 * If this changes we have to grab locks in qmerge_add() and qmerge_del().
344 */
345 static int
346 dmult_enque(opaque_t queuep, struct buf *in_bp)
347 {
348 struct fc_data *dmultp = (struct fc_data *)queuep;
455 * Duplexed Commands per Device: Read Queue and Write Queue
456 */
457 /*
458 * Local Function Prototypes
459 */
460 static int duplx_restart();
461
462 static int duplx_init(opaque_t queuep, opaque_t tgcom_objp, opaque_t que_objp,
463 void *lkarg);
464 static int duplx_free(struct flc_obj *flcobjp);
465 static int duplx_enque(opaque_t queuep, struct buf *bp);
466 static int duplx_deque(opaque_t queuep, struct buf *bp);
467
468 struct flc_objops duplx_ops = {
469 duplx_init,
470 duplx_free,
471 duplx_enque,
472 duplx_deque,
473 fc_start_kstat,
474 fc_stop_kstat,
475 { NULL, NULL }
476 };
477
478 struct flc_obj *
479 duplx_create()
480 {
481 struct flc_obj *flcobjp;
482 struct duplx_data *fcdp;
483
484 flcobjp = kmem_zalloc((sizeof (*flcobjp) + sizeof (*fcdp)), KM_NOSLEEP);
485 if (!flcobjp)
486 return (NULL);
487
488 fcdp = (struct duplx_data *)(flcobjp+1);
489 flcobjp->flc_data = (opaque_t)fcdp;
490 flcobjp->flc_ops = &duplx_ops;
491
492 fcdp->ds_writeq.fc_qobjp = qfifo_create();
493 if (!(fcdp->ds_writeq.fc_qobjp = qfifo_create())) {
494 kmem_free(flcobjp, (sizeof (*flcobjp) + sizeof (*fcdp)));
495 return (NULL);
679 duplx_restart(struct duplx_data *duplxp)
680 {
681 (void) duplx_enque(duplxp, NULL);
682 return (-1);
683 }
684
685 /*
686 * Tagged queueing flow control
687 */
688 /*
689 * Local Function Prototypes
690 */
691
692 struct flc_objops adapt_ops = {
693 fc_init,
694 fc_free,
695 dmult_enque,
696 dmult_deque,
697 fc_start_kstat,
698 fc_stop_kstat,
699 { NULL, NULL }
700 };
701
702 struct flc_obj *
703 adapt_create()
704 {
705 return (fc_create((struct flc_objops *)&adapt_ops));
706
707 }
708
709 /*
710 * Common Queue functions
711 */
712
713 /*
714 * Local static data
715 */
716 #ifdef Q_DEBUG
717 #define DENT 0x0001
718 #define DERR 0x0002
719 #define DIO 0x0004
775 qfp->q_tab.b_actl = NULL;
776 bp->av_forw = 0;
777 }
778 return (bp);
779 }
780
781
782
783 /*
784 * Qmerge
785 * Local Function Prototypes
786 */
787 static int qmerge_add(), qmerge_free();
788 static struct buf *qmerge_del(struct que_data *qfp);
789
790 struct que_objops qmerge_ops = {
791 que_init,
792 qmerge_free,
793 qmerge_add,
794 qmerge_del,
795 { NULL, NULL }
796 };
797
798 /* fields in diskhd */
799 #define hd_cnt b_back
800 #define hd_private b_forw
801 #define hd_flags b_flags
802 #define hd_sync_next av_forw
803 #define hd_async_next av_back
804
805 #define hd_sync2async sync_async_ratio
806
807 #define QNEAR_FORWARD 0x01
808 #define QNEAR_BACKWARD 0x02
809 #define QNEAR_ASYNCONLY 0x04
810 #define QNEAR_ASYNCALSO 0x08
811
812 #define DBLK(bp) ((unsigned long)(bp)->b_private)
813
814 #define BP_LT_BP(a, b) (DBLK(a) < DBLK(b))
815 #define BP_GT_BP(a, b) (DBLK(a) > DBLK(b))
1316 }
1317 qmerge_mergesetup(bp_merge, next_bp);
1318 }
1319 return (bp_merge);
1320 }
1321
1322
1323 /*
1324 * FIFO Queue functions
1325 */
1326 /*
1327 * Local Function Prototypes
1328 */
1329 static int qfifo_add();
1330
1331 struct que_objops qfifo_ops = {
1332 que_init,
1333 que_free,
1334 qfifo_add,
1335 que_del,
1336 { NULL, NULL }
1337 };
1338
1339 /*
1340 * Local static data
1341 */
1342 struct que_obj *
1343 qfifo_create()
1344 {
1345 return (que_create((struct que_objops *)&qfifo_ops));
1346 }
1347
1348 static int
1349 qfifo_add(struct que_data *qfp, struct buf *bp)
1350 {
1351
1352 if (!qfp->q_tab.b_actf)
1353 qfp->q_tab.b_actf = bp;
1354 else
1355 qfp->q_tab.b_actl->av_forw = bp;
1356 qfp->q_tab.b_actl = bp;
1357 bp->av_forw = NULL;
1358 return (0);
1359 }
1360
1361 /*
1362 * One-Way-Scan Queue functions
1363 */
1364 /*
1365 * Local Function Prototypes
1366 */
1367 static int qsort_add();
1368 static struct buf *qsort_del();
1369 static void oneway_scan_binary(struct diskhd *dp, struct buf *bp);
1370
1371 struct que_objops qsort_ops = {
1372 que_init,
1373 que_free,
1374 qsort_add,
1375 qsort_del,
1376 { NULL, NULL }
1377 };
1378
1379 /*
1380 * Local static data
1381 */
1382 struct que_obj *
1383 qsort_create()
1384 {
1385 return (que_create((struct que_objops *)&qsort_ops));
1386 }
1387
1388 static int
1389 qsort_add(struct que_data *qfp, struct buf *bp)
1390 {
1391 qfp->q_cnt++;
1392 oneway_scan_binary(&qfp->q_tab, bp);
1393 return (0);
1394 }
1395
1396
1438 bp->av_forw = 0;
1439 if (!qfp->q_tab.b_actf && qfp->q_tab.b_pasf) {
1440 qfp->q_tab.b_actf = qfp->q_tab.b_pasf;
1441 qfp->q_tab.b_pasf = NULL;
1442 }
1443 return (bp);
1444 }
1445
1446 /*
1447 * Tagged queueing
1448 */
1449 /*
1450 * Local Function Prototypes
1451 */
1452
1453 struct que_objops qtag_ops = {
1454 que_init,
1455 que_free,
1456 qsort_add,
1457 qsort_del,
1458 { NULL, NULL }
1459 };
1460
1461 /*
1462 * Local static data
1463 */
1464 struct que_obj *
1465 qtag_create()
1466 {
1467 return (que_create((struct que_objops *)&qtag_ops));
1468 }
|