1 /* $NetBSD: rf.c,v 1.7 2004/10/28 07:07:41 yamt Exp $ */ 2 /* 3 * Copyright (c) 2002 Jochen Kunz. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 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 Jochen Kunz may not be used to endorse or promote 15 * products derived from this software without specific prior 16 * written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY JOCHEN KUNZ 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JOCHEN KUNZ 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* 32 TODO: 33 - Better LBN bound checking, block padding for SD disks. 34 - Formatting / "Set Density" 35 - Better error handling / detailed error reason reportnig. 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: rf.c,v 1.7 2004/10/28 07:07:41 yamt Exp $"); 40 41 /* autoconfig stuff */ 42 #include <sys/param.h> 43 #include <sys/device.h> 44 #include <sys/conf.h> 45 #include "locators.h" 46 #include "ioconf.h" 47 48 /* bus_space / bus_dma */ 49 #include <machine/bus.h> 50 51 /* UniBus / QBus specific stuff */ 52 #include <dev/qbus/ubavar.h> 53 54 /* disk interface */ 55 #include <sys/types.h> 56 #include <sys/disklabel.h> 57 #include <sys/disk.h> 58 59 /* general system data and functions */ 60 #include <sys/systm.h> 61 #include <sys/ioctl.h> 62 #include <sys/ioccom.h> 63 64 /* physio / buffer handling */ 65 #include <sys/buf.h> 66 #include <sys/bufq.h> 67 68 /* tsleep / sleep / wakeup */ 69 #include <sys/proc.h> 70 /* hz for above */ 71 #include <sys/kernel.h> 72 73 /* bitdefinitions for RX211 */ 74 #include <dev/qbus/rfreg.h> 75 76 77 #define RFS_DENS 0x0001 /* single or double density */ 78 #define RFS_AD 0x0002 /* density auto detect */ 79 #define RFS_NOTINIT 0x0000 /* not initialized */ 80 #define RFS_PROBING 0x0010 /* density detect / verify started */ 81 #define RFS_FBUF 0x0020 /* Fill Buffer */ 82 #define RFS_EBUF 0x0030 /* Empty Buffer */ 83 #define RFS_WSEC 0x0040 /* Write Sector */ 84 #define RFS_RSEC 0x0050 /* Read Sector */ 85 #define RFS_SMD 0x0060 /* Set Media Density */ 86 #define RFS_RSTAT 0x0070 /* Read Status */ 87 #define RFS_WDDS 0x0080 /* Write Deleted Data Sector */ 88 #define RFS_REC 0x0090 /* Read Error Code */ 89 #define RFS_IDLE 0x00a0 /* controller is idle */ 90 #define RFS_CMDS 0x00f0 /* command mask */ 91 #define RFS_OPEN_A 0x0100 /* partition a open */ 92 #define RFS_OPEN_B 0x0200 /* partition b open */ 93 #define RFS_OPEN_C 0x0400 /* partition c open */ 94 #define RFS_OPEN_MASK 0x0f00 /* mask for open partitions */ 95 #define RFS_OPEN_SHIFT 8 /* to shift 1 to get RFS_OPEN_A */ 96 #define RFS_SETCMD(rf, state) ((rf) = ((rf) & ~RFS_CMDS) | (state)) 97 98 99 100 /* autoconfig stuff */ 101 static int rfc_match(struct device *, struct cfdata *, void *); 102 static void rfc_attach(struct device *, struct device *, void *); 103 static int rf_match(struct device *, struct cfdata *, void *); 104 static void rf_attach(struct device *, struct device *, void *); 105 static int rf_print(void *, const char *); 106 107 /* device interface functions / interface to disk(9) */ 108 dev_type_open(rfopen); 109 dev_type_close(rfclose); 110 dev_type_read(rfread); 111 dev_type_write(rfwrite); 112 dev_type_ioctl(rfioctl); 113 dev_type_strategy(rfstrategy); 114 dev_type_dump(rfdump); 115 dev_type_size(rfsize); 116 117 118 /* Entries in block and character major device number switch table. */ 119 const struct bdevsw rf_bdevsw = { 120 rfopen, 121 rfclose, 122 rfstrategy, 123 rfioctl, 124 rfdump, 125 rfsize, 126 D_DISK 127 }; 128 129 const struct cdevsw rf_cdevsw = { 130 rfopen, 131 rfclose, 132 rfread, 133 rfwrite, 134 rfioctl, 135 nostop, 136 notty, 137 nopoll, 138 nommap, 139 nokqfilter, 140 D_DISK 141 }; 142 143 144 145 struct rfc_softc { 146 struct device sc_dev; /* common device data */ 147 struct device *sc_childs[2]; /* child devices */ 148 struct evcnt sc_intr_count; /* Interrupt counter for statistics */ 149 struct buf *sc_curbuf; /* buf that is currently in work */ 150 bus_space_tag_t sc_iot; /* bus_space I/O tag */ 151 bus_space_handle_t sc_ioh; /* bus_space I/O handle */ 152 bus_dma_tag_t sc_dmat; /* bus_dma DMA tag */ 153 bus_dmamap_t sc_dmam; /* bus_dma DMA map */ 154 caddr_t sc_bufidx; /* current position in buffer data */ 155 int sc_curchild; /* child whos bufq is in work */ 156 int sc_bytesleft; /* bytes left to transfer */ 157 u_int8_t type; /* controller type, 1 or 2 */ 158 }; 159 160 161 162 CFATTACH_DECL( 163 rfc, 164 sizeof(struct rfc_softc), 165 rfc_match, 166 rfc_attach, 167 NULL, 168 NULL 169 ); 170 171 172 173 struct rf_softc { 174 struct device sc_dev; /* common device data */ 175 struct disk sc_disk; /* common disk device data */ 176 struct bufq_state sc_bufq; /* queue of pending transfers */ 177 int sc_state; /* state of drive */ 178 u_int8_t sc_dnum; /* drive number, 0 or 1 */ 179 }; 180 181 182 183 CFATTACH_DECL( 184 rf, 185 sizeof(struct rf_softc), 186 rf_match, 187 rf_attach, 188 NULL, 189 NULL 190 ); 191 192 193 194 struct rfc_attach_args { 195 u_int8_t type; /* controller type, 1 or 2 */ 196 u_int8_t dnum; /* drive number, 0 or 1 */ 197 }; 198 199 200 201 struct dkdriver rfdkdriver = { 202 rfstrategy 203 }; 204 205 206 207 /* helper functions */ 208 int rfc_sendcmd(struct rfc_softc *, int, int, int); 209 struct rf_softc* get_new_buf( struct rfc_softc *); 210 static void rfc_intr(void *); 211 212 213 214 /* 215 * Issue a reset command to the controller and look for the bits in 216 * RX2CS and RX2ES. 217 * RX2CS_RX02 and / or RX2CS_DD can be set, 218 * RX2ES has to be set, all other bits must be 0 219 */ 220 int 221 rfc_match(struct device *parent, struct cfdata *match, void *aux) 222 { 223 struct uba_attach_args *ua = aux; 224 int i; 225 226 /* Issue reset command. */ 227 bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS, RX2CS_INIT); 228 /* Wait for the controller to become ready, that is when 229 * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set. */ 230 for (i = 0 ; i < 20 ; i++) { 231 if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS) 232 & RX2CS_DONE) != 0 233 && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES) 234 & (RX2ES_RDY | RX2ES_ID)) != 0) 235 break; 236 DELAY(100000); /* wait 100ms */ 237 } 238 /* 239 * Give up if the timeout has elapsed 240 * and the controller is not ready. 241 */ 242 if (i >= 20) 243 return(0); 244 /* 245 * Issue a Read Status command with interrupt enabled. 246 * The uba(4) driver wants to catch the interrupt to get the 247 * interrupt vector and level of the device 248 */ 249 bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS, 250 RX2CS_RSTAT | RX2CS_IE); 251 /* 252 * Wait for command to finish, ignore errors and 253 * abort if the controller does not respond within the timeout 254 */ 255 for (i = 0 ; i < 20 ; i++) { 256 if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS) 257 & (RX2CS_DONE | RX2CS_IE)) != 0 258 && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES) 259 & RX2ES_RDY) != 0 ) 260 return(1); 261 DELAY(100000); /* wait 100ms */ 262 } 263 return(0); 264 } 265 266 267 268 /* #define RX02_PROBE 1 */ 269 #ifdef RX02_PROBE 270 /* 271 * Probe the density of an inserted floppy disk. 272 * This is done by reading a sector from disk. 273 * Return -1 on error, 0 on SD and 1 on DD. 274 */ 275 int rfcprobedens(struct rfc_softc *, int); 276 int 277 rfcprobedens(struct rfc_softc *rfc_sc, int dnum) 278 { 279 int dens_flag; 280 int i; 281 282 dens_flag = 0; 283 do { 284 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, 285 RX2CS_RSEC | (dens_flag == 0 ? 0 : RX2CS_DD) 286 | (dnum == 0 ? 0 : RX2CS_US)); 287 /* 288 * Transfer request set? 289 * Wait 50us, the controller needs this time to setle 290 */ 291 DELAY(50); 292 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 293 & RX2CS_TR) == 0) { 294 printf("%s: did not respond to Read Sector CMD(1)\n", 295 rfc_sc->sc_dev.dv_xname); 296 return(-1); 297 } 298 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2SA, 1); 299 /* Wait 50us, the controller needs this time to setle */ 300 DELAY(50); 301 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 302 & RX2CS_TR) == 0) { 303 printf("%s: did not respond to Read Sector CMD(2)\n", 304 rfc_sc->sc_dev.dv_xname); 305 return(-1); 306 } 307 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2TA, 1); 308 /* Wait for the command to finish */ 309 for (i = 0 ; i < 200 ; i++) { 310 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 311 RX2CS) & RX2CS_DONE) != 0) 312 break; 313 DELAY(10000); /* wait 10ms */ 314 } 315 if (i >= 200) { 316 printf("%s: did not respond to Read Sector CMD(3)\n", 317 rfc_sc->sc_dev.dv_xname); 318 return(-1); 319 } 320 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 321 & RX2CS_ERR) == 0) 322 return(dens_flag); 323 } while (rfc_sc->type == 2 && dens_flag++ == 0); 324 return(-1); 325 } 326 #endif /* RX02_PROBE */ 327 328 329 330 void 331 rfc_attach(struct device *parent, struct device *self, void *aux) 332 { 333 struct rfc_softc *rfc_sc = (struct rfc_softc *)self; 334 struct uba_attach_args *ua = aux; 335 struct rfc_attach_args rfc_aa; 336 int i; 337 338 rfc_sc->sc_iot = ua->ua_iot; 339 rfc_sc->sc_ioh = ua->ua_ioh; 340 rfc_sc->sc_dmat = ua->ua_dmat; 341 rfc_sc->sc_curbuf = NULL; 342 /* Tell the QBus busdriver about our interrupt handler. */ 343 uba_intr_establish(ua->ua_icookie, ua->ua_cvec, rfc_intr, rfc_sc, 344 &rfc_sc->sc_intr_count); 345 /* Attach to the interrupt counter, see evcnt(9) */ 346 evcnt_attach_dynamic(&rfc_sc->sc_intr_count, EVCNT_TYPE_INTR, 347 ua->ua_evcnt, rfc_sc->sc_dev.dv_xname, "intr"); 348 /* get a bus_dma(9) handle */ 349 i = bus_dmamap_create(rfc_sc->sc_dmat, RX2_BYTE_DD, 1, RX2_BYTE_DD, 0, 350 BUS_DMA_ALLOCNOW, &rfc_sc->sc_dmam); 351 if (i != 0) { 352 printf("rfc_attach: Error creating bus dma map: %d\n", i); 353 return; 354 } 355 356 /* Issue reset command. */ 357 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, RX2CS_INIT); 358 /* 359 * Wait for the controller to become ready, that is when 360 * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set. 361 */ 362 for (i = 0 ; i < 20 ; i++) { 363 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 364 & RX2CS_DONE) != 0 365 && (bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2ES) 366 & (RX2ES_RDY | RX2ES_ID)) != 0) 367 break; 368 DELAY(100000); /* wait 100ms */ 369 } 370 /* 371 * Give up if the timeout has elapsed 372 * and the controller is not ready. 373 */ 374 if (i >= 20) { 375 printf(": did not respond to INIT CMD\n"); 376 return; 377 } 378 /* Is ths a RX01 or a RX02? */ 379 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 380 & RX2CS_RX02) != 0) { 381 rfc_sc->type = 2; 382 rfc_aa.type = 2; 383 } else { 384 rfc_sc->type = 1; 385 rfc_aa.type = 1; 386 } 387 printf(": RX0%d\n", rfc_sc->type); 388 389 #ifndef RX02_PROBE 390 /* 391 * Bouth disk drievs and the controller are one physical unit. 392 * If we found the controller, there will be bouth disk drievs. 393 * So attach them. 394 */ 395 rfc_aa.dnum = 0; 396 rfc_sc->sc_childs[0] = config_found(&rfc_sc->sc_dev, &rfc_aa,rf_print); 397 rfc_aa.dnum = 1; 398 rfc_sc->sc_childs[1] = config_found(&rfc_sc->sc_dev, &rfc_aa,rf_print); 399 #else /* RX02_PROBE */ 400 /* 401 * There are clones of the DEC RX system with standard shugart 402 * interface. In this case we can not be sure that there are 403 * bouth disk drievs. So we want to do a detection of attached 404 * drives. This is done by reading a sector from disk. This means 405 * that there must be a formatted disk in the drive at boot time. 406 * This is bad, but I did not find another way to detect the 407 * (non)existence of a floppy drive. 408 */ 409 if (rfcprobedens(rfc_sc, 0) >= 0) { 410 rfc_aa.dnum = 0; 411 rfc_sc->sc_childs[0] = config_found(&rfc_sc->sc_dev, &rfc_aa, 412 rf_print); 413 } else 414 rfc_sc->sc_childs[0] = NULL; 415 if (rfcprobedens(rfc_sc, 1) >= 0) { 416 rfc_aa.dnum = 1; 417 rfc_sc->sc_childs[1] = config_found(&rfc_sc->sc_dev, &rfc_aa, 418 rf_print); 419 } else 420 rfc_sc->sc_childs[1] = NULL; 421 #endif /* RX02_PROBE */ 422 return; 423 } 424 425 426 427 int 428 rf_match(struct device *parent, struct cfdata *match, void *aux) 429 { 430 struct rfc_attach_args *rfc_aa = aux; 431 432 /* 433 * Only attach if the locator is wildcarded or 434 * if the specified locator addresses the current device. 435 */ 436 if (match->cf_loc[RFCCF_DRIVE] == RFCCF_DRIVE_DEFAULT || 437 match->cf_loc[RFCCF_DRIVE] == rfc_aa->dnum) 438 return(1); 439 return(0); 440 } 441 442 443 444 void 445 rf_attach(struct device *parent, struct device *self, void *aux) 446 { 447 struct rf_softc *rf_sc = (struct rf_softc *)self; 448 struct rfc_attach_args *rfc_aa = (struct rfc_attach_args *)aux; 449 struct rfc_softc *rfc_sc; 450 struct disklabel *dl; 451 452 rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent; 453 rf_sc->sc_dnum = rfc_aa->dnum; 454 rf_sc->sc_state = 0; 455 rf_sc->sc_disk.dk_name = rf_sc->sc_dev.dv_xname; 456 rf_sc->sc_disk.dk_driver = &rfdkdriver; 457 disk_attach(&rf_sc->sc_disk); 458 dl = rf_sc->sc_disk.dk_label; 459 dl->d_type = DTYPE_FLOPPY; /* drive type */ 460 dl->d_magic = DISKMAGIC; /* the magic number */ 461 dl->d_magic2 = DISKMAGIC; 462 dl->d_typename[0] = 'R'; 463 dl->d_typename[1] = 'X'; 464 dl->d_typename[2] = '0'; 465 dl->d_typename[3] = rfc_sc->type == 1 ? '1' : '2'; /* type name */ 466 dl->d_typename[4] = '\0'; 467 dl->d_secsize = DEV_BSIZE; /* bytes per sector */ 468 /* 469 * Fill in some values to have a initialized data structure. Some 470 * values will be reset by rfopen() depending on the actual density. 471 */ 472 dl->d_nsectors = RX2_SECTORS; /* sectors per track */ 473 dl->d_ntracks = 1; /* tracks per cylinder */ 474 dl->d_ncylinders = RX2_TRACKS; /* cylinders per unit */ 475 dl->d_secpercyl = RX2_SECTORS; /* sectors per cylinder */ 476 dl->d_secperunit = RX2_SECTORS * RX2_TRACKS; /* sectors per unit */ 477 dl->d_rpm = 360; /* rotational speed */ 478 dl->d_interleave = 1; /* hardware sector interleave */ 479 /* number of partitions in following */ 480 dl->d_npartitions = MAXPARTITIONS; 481 dl->d_bbsize = 0; /* size of boot area at sn0, bytes */ 482 dl->d_sbsize = 0; /* max size of fs superblock, bytes */ 483 /* number of sectors in partition */ 484 dl->d_partitions[0].p_size = 501; 485 dl->d_partitions[0].p_offset = 0; /* starting sector */ 486 dl->d_partitions[0].p_fsize = 0; /* fs basic fragment size */ 487 dl->d_partitions[0].p_fstype = 0; /* fs type */ 488 dl->d_partitions[0].p_frag = 0; /* fs fragments per block */ 489 dl->d_partitions[1].p_size = RX2_SECTORS * RX2_TRACKS / 2; 490 dl->d_partitions[1].p_offset = 0; /* starting sector */ 491 dl->d_partitions[1].p_fsize = 0; /* fs basic fragment size */ 492 dl->d_partitions[1].p_fstype = 0; /* fs type */ 493 dl->d_partitions[1].p_frag = 0; /* fs fragments per block */ 494 dl->d_partitions[2].p_size = RX2_SECTORS * RX2_TRACKS; 495 dl->d_partitions[2].p_offset = 0; /* starting sector */ 496 dl->d_partitions[2].p_fsize = 0; /* fs basic fragment size */ 497 dl->d_partitions[2].p_fstype = 0; /* fs type */ 498 dl->d_partitions[2].p_frag = 0; /* fs fragments per block */ 499 bufq_alloc(&rf_sc->sc_bufq, BUFQ_DISKSORT | BUFQ_SORT_CYLINDER); 500 printf("\n"); 501 return; 502 } 503 504 505 506 int 507 rf_print(void *aux, const char *name) 508 { 509 struct rfc_attach_args *rfc_aa = aux; 510 511 if (name != NULL) 512 aprint_normal("RX0%d at %s", rfc_aa->type, name); 513 aprint_normal(" drive %d", rfc_aa->dnum); 514 return(UNCONF); 515 } 516 517 518 519 /* Send a command to the controller */ 520 int 521 rfc_sendcmd(struct rfc_softc *rfc_sc, int cmd, int data1, int data2) 522 { 523 524 /* Write command to CSR. */ 525 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, cmd); 526 /* Wait 50us, the controller needs this time to setle. */ 527 DELAY(50); 528 /* Write parameter 1 to DBR */ 529 if ((cmd & RX2CS_FC) != RX2CS_RSTAT) { 530 /* Transfer request set? */ 531 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 532 & RX2CS_TR) == 0) { 533 printf("%s: did not respond to CMD %x (1)\n", 534 rfc_sc->sc_dev.dv_xname, cmd); 535 return(-1); 536 } 537 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB, 538 data1); 539 } 540 /* Write parameter 2 to DBR */ 541 if ((cmd & RX2CS_FC) <= RX2CS_RSEC || (cmd & RX2CS_FC) == RX2CS_WDDS) { 542 /* Wait 50us, the controller needs this time to setle. */ 543 DELAY(50); 544 /* Transfer request set? */ 545 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 546 & RX2CS_TR) == 0) { 547 printf("%s: did not respond to CMD %x (2)\n", 548 rfc_sc->sc_dev.dv_xname, cmd); 549 return(-1); 550 } 551 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB, 552 data2); 553 } 554 return(1); 555 } 556 557 558 559 void 560 rfstrategy(struct buf *buf) 561 { 562 struct rf_softc *rf_sc; 563 struct rfc_softc *rfc_sc; 564 int i; 565 566 i = DISKUNIT(buf->b_dev); 567 if (i >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[i]) == NULL) { 568 buf->b_flags |= B_ERROR; 569 buf->b_error = ENXIO; 570 biodone(buf); 571 return; 572 } 573 rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent; 574 /* We are going to operate on a non-open dev? PANIC! */ 575 if ((rf_sc->sc_state & 1 << (DISKPART(buf->b_dev) + RFS_OPEN_SHIFT)) 576 == 0) 577 panic("rfstrategy: can not operate on non-open drive %s " 578 "partition %d", rf_sc->sc_dev.dv_xname, 579 DISKPART(buf->b_dev)); 580 if (buf->b_bcount == 0) { 581 biodone(buf); 582 return; 583 } 584 /* 585 * BUFQ_PUT() operates on b_rawblkno. rfstrategy() gets 586 * only b_blkno that is partition relative. As a floppy does not 587 * have partitions b_rawblkno == b_blkno. 588 */ 589 buf->b_rawblkno = buf->b_blkno; 590 /* 591 * from sys/kern/subr_disk.c: 592 * Seek sort for disks. We depend on the driver which calls us using 593 * b_resid as the current cylinder number. 594 */ 595 i = splbio(); 596 if (rfc_sc->sc_curbuf == NULL) { 597 rfc_sc->sc_curchild = rf_sc->sc_dnum; 598 rfc_sc->sc_curbuf = buf; 599 rfc_sc->sc_bufidx = buf->b_un.b_addr; 600 rfc_sc->sc_bytesleft = buf->b_bcount; 601 rfc_intr(rfc_sc); 602 } else { 603 buf->b_resid = buf->b_blkno / RX2_SECTORS; 604 BUFQ_PUT(&rf_sc->sc_bufq, buf); 605 buf->b_resid = 0; 606 } 607 splx(i); 608 return; 609 } 610 611 612 613 /* 614 * Look if there is another buffer in the bufferqueue of this drive 615 * and start to process it if there is one. 616 * If the bufferqueue is empty, look at the bufferqueue of the other drive 617 * that is attached to this controller. 618 * Start procesing the bufferqueue of the other drive if it isn't empty. 619 * Return a pointer to the softc structure of the drive that is now 620 * ready to process a buffer or NULL if there is no buffer in either queues. 621 */ 622 struct rf_softc* 623 get_new_buf( struct rfc_softc *rfc_sc) 624 { 625 struct rf_softc *rf_sc; 626 struct rf_softc *other_drive; 627 628 rf_sc = (struct rf_softc *)rfc_sc->sc_childs[rfc_sc->sc_curchild]; 629 rfc_sc->sc_curbuf = BUFQ_GET(&rf_sc->sc_bufq); 630 if (rfc_sc->sc_curbuf != NULL) { 631 rfc_sc->sc_bufidx = rfc_sc->sc_curbuf->b_un.b_addr; 632 rfc_sc->sc_bytesleft = rfc_sc->sc_curbuf->b_bcount; 633 } else { 634 RFS_SETCMD(rf_sc->sc_state, RFS_IDLE); 635 other_drive = (struct rf_softc *) 636 rfc_sc->sc_childs[ rfc_sc->sc_curchild == 0 ? 1 : 0]; 637 if (other_drive != NULL 638 && BUFQ_PEEK(&other_drive->sc_bufq) != NULL) { 639 rfc_sc->sc_curchild = rfc_sc->sc_curchild == 0 ? 1 : 0; 640 rf_sc = other_drive; 641 rfc_sc->sc_curbuf = BUFQ_GET(&rf_sc->sc_bufq); 642 rfc_sc->sc_bufidx = rfc_sc->sc_curbuf->b_un.b_addr; 643 rfc_sc->sc_bytesleft = rfc_sc->sc_curbuf->b_bcount; 644 } else 645 return(NULL); 646 } 647 return(rf_sc); 648 } 649 650 651 652 void 653 rfc_intr(void *intarg) 654 { 655 struct rfc_softc *rfc_sc = intarg; 656 struct rf_softc *rf_sc; 657 int i; 658 659 rf_sc = (struct rf_softc *)rfc_sc->sc_childs[rfc_sc->sc_curchild]; 660 do { 661 /* 662 * First clean up from previous command... 663 */ 664 switch (rf_sc->sc_state & RFS_CMDS) { 665 case RFS_PROBING: /* density detect / verify started */ 666 disk_unbusy(&rf_sc->sc_disk, 0, 1); 667 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 668 RX2CS) & RX2CS_ERR) == 0) { 669 RFS_SETCMD(rf_sc->sc_state, RFS_IDLE); 670 wakeup(rf_sc); 671 } else { 672 if (rfc_sc->type == 2 673 && (rf_sc->sc_state & RFS_DENS) == 0 674 && (rf_sc->sc_state & RFS_AD) != 0) { 675 /* retry at DD */ 676 rf_sc->sc_state |= RFS_DENS; 677 disk_busy(&rf_sc->sc_disk); 678 if (rfc_sendcmd(rfc_sc, RX2CS_RSEC 679 | RX2CS_IE | RX2CS_DD | 680 (rf_sc->sc_dnum == 0 ? 0 : 681 RX2CS_US), 1, 1) < 0) { 682 disk_unbusy(&rf_sc->sc_disk, 683 0, 1); 684 RFS_SETCMD(rf_sc->sc_state, 685 RFS_NOTINIT); 686 wakeup(rf_sc); 687 } 688 } else { 689 printf("%s: density error.\n", 690 rf_sc->sc_dev.dv_xname); 691 RFS_SETCMD(rf_sc->sc_state,RFS_NOTINIT); 692 wakeup(rf_sc); 693 } 694 } 695 return; 696 case RFS_IDLE: /* controller is idle */ 697 if (rfc_sc->sc_curbuf->b_bcount 698 % ((rf_sc->sc_state & RFS_DENS) == 0 699 ? RX2_BYTE_SD : RX2_BYTE_DD) != 0) { 700 /* 701 * can only handle blocks that are a multiple 702 * of the physical block size 703 */ 704 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 705 } 706 RFS_SETCMD(rf_sc->sc_state, (rfc_sc->sc_curbuf->b_flags 707 & B_READ) != 0 ? RFS_RSEC : RFS_FBUF); 708 break; 709 case RFS_RSEC: /* Read Sector */ 710 disk_unbusy(&rf_sc->sc_disk, 0, 1); 711 /* check for errors */ 712 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 713 RX2CS) & RX2CS_ERR) != 0) { 714 /* should do more verbose error reporting */ 715 printf("rfc_intr: Error reading secotr: %x\n", 716 bus_space_read_2(rfc_sc->sc_iot, 717 rfc_sc->sc_ioh, RX2ES) ); 718 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 719 } 720 RFS_SETCMD(rf_sc->sc_state, RFS_EBUF); 721 break; 722 case RFS_WSEC: /* Write Sector */ 723 i = (rf_sc->sc_state & RFS_DENS) == 0 724 ? RX2_BYTE_SD : RX2_BYTE_DD; 725 disk_unbusy(&rf_sc->sc_disk, i, 0); 726 /* check for errors */ 727 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 728 RX2CS) & RX2CS_ERR) != 0) { 729 /* should do more verbose error reporting */ 730 printf("rfc_intr: Error writing secotr: %x\n", 731 bus_space_read_2(rfc_sc->sc_iot, 732 rfc_sc->sc_ioh, RX2ES) ); 733 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 734 break; 735 } 736 if (rfc_sc->sc_bytesleft > i) { 737 rfc_sc->sc_bytesleft -= i; 738 rfc_sc->sc_bufidx += i; 739 } else { 740 biodone(rfc_sc->sc_curbuf); 741 rf_sc = get_new_buf( rfc_sc); 742 if (rf_sc == NULL) 743 return; 744 } 745 RFS_SETCMD(rf_sc->sc_state, 746 (rfc_sc->sc_curbuf->b_flags & B_READ) != 0 747 ? RFS_RSEC : RFS_FBUF); 748 break; 749 case RFS_FBUF: /* Fill Buffer */ 750 disk_unbusy(&rf_sc->sc_disk, 0, 0); 751 bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam); 752 /* check for errors */ 753 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 754 RX2CS) & RX2CS_ERR) != 0) { 755 /* should do more verbose error reporting */ 756 printf("rfc_intr: Error while DMA: %x\n", 757 bus_space_read_2(rfc_sc->sc_iot, 758 rfc_sc->sc_ioh, RX2ES)); 759 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 760 } 761 RFS_SETCMD(rf_sc->sc_state, RFS_WSEC); 762 break; 763 case RFS_EBUF: /* Empty Buffer */ 764 i = (rf_sc->sc_state & RFS_DENS) == 0 765 ? RX2_BYTE_SD : RX2_BYTE_DD; 766 disk_unbusy(&rf_sc->sc_disk, i, 1); 767 bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam); 768 /* check for errors */ 769 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 770 RX2CS) & RX2CS_ERR) != 0) { 771 /* should do more verbose error reporting */ 772 printf("rfc_intr: Error while DMA: %x\n", 773 bus_space_read_2(rfc_sc->sc_iot, 774 rfc_sc->sc_ioh, RX2ES)); 775 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 776 break; 777 } 778 if (rfc_sc->sc_bytesleft > i) { 779 rfc_sc->sc_bytesleft -= i; 780 rfc_sc->sc_bufidx += i; 781 } else { 782 biodone(rfc_sc->sc_curbuf); 783 rf_sc = get_new_buf( rfc_sc); 784 if (rf_sc == NULL) 785 return; 786 } 787 RFS_SETCMD(rf_sc->sc_state, 788 (rfc_sc->sc_curbuf->b_flags & B_READ) != 0 789 ? RFS_RSEC : RFS_FBUF); 790 break; 791 case RFS_NOTINIT: /* Device is not open */ 792 case RFS_SMD: /* Set Media Density */ 793 case RFS_RSTAT: /* Read Status */ 794 case RFS_WDDS: /* Write Deleted Data Sector */ 795 case RFS_REC: /* Read Error Code */ 796 default: 797 panic("Impossible state in rfc_intr(1).\n"); 798 } 799 800 if ((rfc_sc->sc_curbuf->b_flags & B_ERROR) != 0) { 801 /* 802 * An error occurred while processing this buffer. 803 * Finish it and try to get a new buffer to process. 804 * Return if there are no buffers in the queues. 805 * This loops until the queues are empty or a new 806 * action was successfully scheduled. 807 */ 808 rfc_sc->sc_curbuf->b_resid = rfc_sc->sc_bytesleft; 809 rfc_sc->sc_curbuf->b_error = EIO; 810 biodone(rfc_sc->sc_curbuf); 811 rf_sc = get_new_buf( rfc_sc); 812 if (rf_sc == NULL) 813 return; 814 continue; 815 } 816 817 /* 818 * ... then initiate next command. 819 */ 820 switch (rf_sc->sc_state & RFS_CMDS) { 821 case RFS_EBUF: /* Empty Buffer */ 822 i = bus_dmamap_load(rfc_sc->sc_dmat, rfc_sc->sc_dmam, 823 rfc_sc->sc_bufidx, (rf_sc->sc_state & RFS_DENS) == 0 824 ? RX2_BYTE_SD : RX2_BYTE_DD, 825 rfc_sc->sc_curbuf->b_proc, BUS_DMA_NOWAIT); 826 if (i != 0) { 827 printf("rfc_intr: Error loading dmamap: %d\n", 828 i); 829 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 830 break; 831 } 832 disk_busy(&rf_sc->sc_disk); 833 if (rfc_sendcmd(rfc_sc, RX2CS_EBUF | RX2CS_IE 834 | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD) 835 | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US) 836 | ((rfc_sc->sc_dmam->dm_segs[0].ds_addr 837 & 0x30000) >>4), ((rf_sc->sc_state & RFS_DENS) == 0 838 ? RX2_BYTE_SD : RX2_BYTE_DD) / 2, 839 rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) { 840 disk_unbusy(&rf_sc->sc_disk, 0, 1); 841 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 842 bus_dmamap_unload(rfc_sc->sc_dmat, 843 rfc_sc->sc_dmam); 844 } 845 break; 846 case RFS_FBUF: /* Fill Buffer */ 847 i = bus_dmamap_load(rfc_sc->sc_dmat, rfc_sc->sc_dmam, 848 rfc_sc->sc_bufidx, (rf_sc->sc_state & RFS_DENS) == 0 849 ? RX2_BYTE_SD : RX2_BYTE_DD, 850 rfc_sc->sc_curbuf->b_proc, BUS_DMA_NOWAIT); 851 if (i != 0) { 852 printf("rfc_intr: Error loading dmamap: %d\n", 853 i); 854 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 855 break; 856 } 857 disk_busy(&rf_sc->sc_disk); 858 if (rfc_sendcmd(rfc_sc, RX2CS_FBUF | RX2CS_IE 859 | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD) 860 | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US) 861 | ((rfc_sc->sc_dmam->dm_segs[0].ds_addr 862 & 0x30000)>>4), ((rf_sc->sc_state & RFS_DENS) == 0 863 ? RX2_BYTE_SD : RX2_BYTE_DD) / 2, 864 rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) { 865 disk_unbusy(&rf_sc->sc_disk, 0, 0); 866 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 867 bus_dmamap_unload(rfc_sc->sc_dmat, 868 rfc_sc->sc_dmam); 869 } 870 break; 871 case RFS_WSEC: /* Write Sector */ 872 i = (rfc_sc->sc_curbuf->b_bcount - rfc_sc->sc_bytesleft 873 + rfc_sc->sc_curbuf->b_blkno * DEV_BSIZE) / 874 ((rf_sc->sc_state & RFS_DENS) == 0 875 ? RX2_BYTE_SD : RX2_BYTE_DD); 876 if (i > RX2_TRACKS * RX2_SECTORS) { 877 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 878 break; 879 } 880 disk_busy(&rf_sc->sc_disk); 881 if (rfc_sendcmd(rfc_sc, RX2CS_WSEC | RX2CS_IE 882 | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US) 883 | ((rf_sc->sc_state& RFS_DENS) == 0 ? 0 : RX2CS_DD), 884 i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) { 885 disk_unbusy(&rf_sc->sc_disk, 0, 0); 886 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 887 } 888 break; 889 case RFS_RSEC: /* Read Sector */ 890 i = (rfc_sc->sc_curbuf->b_bcount - rfc_sc->sc_bytesleft 891 + rfc_sc->sc_curbuf->b_blkno * DEV_BSIZE) / 892 ((rf_sc->sc_state & RFS_DENS) == 0 893 ? RX2_BYTE_SD : RX2_BYTE_DD); 894 if (i > RX2_TRACKS * RX2_SECTORS) { 895 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 896 break; 897 } 898 disk_busy(&rf_sc->sc_disk); 899 if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE 900 | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US) 901 | ((rf_sc->sc_state& RFS_DENS) == 0 ? 0 : RX2CS_DD), 902 i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) { 903 disk_unbusy(&rf_sc->sc_disk, 0, 1); 904 rfc_sc->sc_curbuf->b_flags |= B_ERROR; 905 } 906 break; 907 case RFS_NOTINIT: /* Device is not open */ 908 case RFS_PROBING: /* density detect / verify started */ 909 case RFS_IDLE: /* controller is idle */ 910 case RFS_SMD: /* Set Media Density */ 911 case RFS_RSTAT: /* Read Status */ 912 case RFS_WDDS: /* Write Deleted Data Sector */ 913 case RFS_REC: /* Read Error Code */ 914 default: 915 panic("Impossible state in rfc_intr(2).\n"); 916 } 917 918 if ((rfc_sc->sc_curbuf->b_flags & B_ERROR) != 0) { 919 /* 920 * An error occurred while processing this buffer. 921 * Finish it and try to get a new buffer to process. 922 * Return if there are no buffers in the queues. 923 * This loops until the queues are empty or a new 924 * action was successfully scheduled. 925 */ 926 rfc_sc->sc_curbuf->b_resid = rfc_sc->sc_bytesleft; 927 rfc_sc->sc_curbuf->b_error = EIO; 928 biodone(rfc_sc->sc_curbuf); 929 rf_sc = get_new_buf( rfc_sc); 930 if (rf_sc == NULL) 931 return; 932 continue; 933 } 934 } while ( 1 == 0 /* CONSTCOND */ ); 935 return; 936 } 937 938 939 940 int 941 rfdump(dev_t dev, daddr_t blkno, caddr_t va, size_t size) 942 { 943 944 /* A 0.5MB floppy is much to small to take a system dump... */ 945 return(ENXIO); 946 } 947 948 949 950 int 951 rfsize(dev_t dev) 952 { 953 954 return(-1); 955 } 956 957 958 959 int 960 rfopen(dev_t dev, int oflags, int devtype, struct proc *p) 961 { 962 struct rf_softc *rf_sc; 963 struct rfc_softc *rfc_sc; 964 struct disklabel *dl; 965 int unit; 966 967 unit = DISKUNIT(dev); 968 if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) { 969 return(ENXIO); 970 } 971 rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent; 972 dl = rf_sc->sc_disk.dk_label; 973 switch (DISKPART(dev)) { 974 case 0: /* Part. a is single density. */ 975 /* opening in single and double density is senseless */ 976 if ((rf_sc->sc_state & RFS_OPEN_B) != 0 ) 977 return(ENXIO); 978 rf_sc->sc_state &= ~RFS_DENS; 979 rf_sc->sc_state &= ~RFS_AD; 980 rf_sc->sc_state |= RFS_OPEN_A; 981 break; 982 case 1: /* Part. b is double density. */ 983 /* 984 * Opening a single density only drive in double 985 * density or simultaneous opening in single and 986 * double density is senseless. 987 */ 988 if (rfc_sc->type == 1 989 || (rf_sc->sc_state & RFS_OPEN_A) != 0 ) 990 return(ENXIO); 991 rf_sc->sc_state |= RFS_DENS; 992 rf_sc->sc_state &= ~RFS_AD; 993 rf_sc->sc_state |= RFS_OPEN_B; 994 break; 995 case 2: /* Part. c is auto density. */ 996 rf_sc->sc_state |= RFS_AD; 997 rf_sc->sc_state |= RFS_OPEN_C; 998 break; 999 default: 1000 return(ENXIO); 1001 break; 1002 } 1003 if ((rf_sc->sc_state & RFS_CMDS) == RFS_NOTINIT) { 1004 rfc_sc->sc_curchild = rf_sc->sc_dnum; 1005 /* 1006 * Controller is idle and density is not detected. 1007 * Start a density probe by issuing a read sector command 1008 * and sleep until the density probe finished. 1009 * Due to this it is imposible to open unformatted media. 1010 * As the RX02/02 is not able to format its own media, 1011 * media must be purchased preformatted. fsck DEC makreting! 1012 */ 1013 RFS_SETCMD(rf_sc->sc_state, RFS_PROBING); 1014 disk_busy(&rf_sc->sc_disk); 1015 if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE 1016 | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US) 1017 | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD), 1018 1, 1) < 0) { 1019 rf_sc->sc_state = 0; 1020 return(ENXIO); 1021 } 1022 /* wait max. 2 sec for density probe to finish */ 1023 if (tsleep(rf_sc, PRIBIO | PCATCH, "density probe", 2 * hz) 1024 != 0 || (rf_sc->sc_state & RFS_CMDS) == RFS_NOTINIT) { 1025 /* timeout elapsed and / or something went wrong */ 1026 rf_sc->sc_state = 0; 1027 return(ENXIO); 1028 } 1029 } 1030 /* disklabel. We use different fake geometries for SD and DD. */ 1031 if ((rf_sc->sc_state & RFS_DENS) == 0) { 1032 dl->d_nsectors = 10; /* sectors per track */ 1033 dl->d_secpercyl = 10; /* sectors per cylinder */ 1034 dl->d_ncylinders = 50; /* cylinders per unit */ 1035 dl->d_secperunit = 501; /* sectors per unit */ 1036 /* number of sectors in partition */ 1037 dl->d_partitions[2].p_size = 500; 1038 } else { 1039 dl->d_nsectors = RX2_SECTORS / 2; /* sectors per track */ 1040 dl->d_secpercyl = RX2_SECTORS / 2; /* sectors per cylinder */ 1041 dl->d_ncylinders = RX2_TRACKS; /* cylinders per unit */ 1042 /* sectors per unit */ 1043 dl->d_secperunit = RX2_SECTORS * RX2_TRACKS / 2; 1044 /* number of sectors in partition */ 1045 dl->d_partitions[2].p_size = RX2_SECTORS * RX2_TRACKS / 2; 1046 } 1047 return(0); 1048 } 1049 1050 1051 1052 int 1053 rfclose(dev_t dev, int fflag, int devtype, struct proc *p) 1054 { 1055 struct rf_softc *rf_sc; 1056 int unit; 1057 1058 unit = DISKUNIT(dev); 1059 if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) { 1060 return(ENXIO); 1061 } 1062 if ((rf_sc->sc_state & 1 << (DISKPART(dev) + RFS_OPEN_SHIFT)) == 0) 1063 panic("rfclose: can not close non-open drive %s " 1064 "partition %d", rf_sc->sc_dev.dv_xname, DISKPART(dev)); 1065 else 1066 rf_sc->sc_state &= ~(1 << (DISKPART(dev) + RFS_OPEN_SHIFT)); 1067 if ((rf_sc->sc_state & RFS_OPEN_MASK) == 0) 1068 rf_sc->sc_state = 0; 1069 return(0); 1070 } 1071 1072 1073 1074 int 1075 rfread(dev_t dev, struct uio *uio, int ioflag) 1076 { 1077 1078 return(physio(rfstrategy, NULL, dev, B_READ, minphys, uio)); 1079 } 1080 1081 1082 1083 int 1084 rfwrite(dev_t dev, struct uio *uio, int ioflag) 1085 { 1086 1087 return(physio(rfstrategy, NULL, dev, B_WRITE, minphys, uio)); 1088 } 1089 1090 1091 1092 int 1093 rfioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) 1094 { 1095 struct rf_softc *rf_sc; 1096 int unit; 1097 1098 unit = DISKUNIT(dev); 1099 if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) { 1100 return(ENXIO); 1101 } 1102 /* We are going to operate on a non-open dev? PANIC! */ 1103 if ((rf_sc->sc_state & 1 << (DISKPART(dev) + RFS_OPEN_SHIFT)) == 0) 1104 panic("rfioctl: can not operate on non-open drive %s " 1105 "partition %d", rf_sc->sc_dev.dv_xname, DISKPART(dev)); 1106 switch (cmd) { 1107 /* get and set disklabel; DIOCGPART used internally */ 1108 case DIOCGDINFO: /* get */ 1109 memcpy(data, rf_sc->sc_disk.dk_label, 1110 sizeof(struct disklabel)); 1111 return(0); 1112 case DIOCSDINFO: /* set */ 1113 return(0); 1114 case DIOCWDINFO: /* set, update disk */ 1115 return(0); 1116 case DIOCGPART: /* get partition */ 1117 ((struct partinfo *)data)->disklab = rf_sc->sc_disk.dk_label; 1118 ((struct partinfo *)data)->part = 1119 &rf_sc->sc_disk.dk_label->d_partitions[DISKPART(dev)]; 1120 return(0); 1121 1122 /* do format operation, read or write */ 1123 case DIOCRFORMAT: 1124 break; 1125 case DIOCWFORMAT: 1126 break; 1127 1128 case DIOCSSTEP: /* set step rate */ 1129 break; 1130 case DIOCSRETRIES: /* set # of retries */ 1131 break; 1132 case DIOCKLABEL: /* keep/drop label on close? */ 1133 break; 1134 case DIOCWLABEL: /* write en/disable label */ 1135 break; 1136 1137 /* case DIOCSBAD: / * set kernel dkbad */ 1138 break; /* */ 1139 case DIOCEJECT: /* eject removable disk */ 1140 break; 1141 case ODIOCEJECT: /* eject removable disk */ 1142 break; 1143 case DIOCLOCK: /* lock/unlock pack */ 1144 break; 1145 1146 /* get default label, clear label */ 1147 case DIOCGDEFLABEL: 1148 break; 1149 case DIOCCLRLABEL: 1150 break; 1151 default: 1152 return(ENOTTY); 1153 } 1154 1155 return(ENOTTY); 1156 } 1157 1158 1159