octeon_ebt3000_cf.c revision 323201
1/***********************license start*************** 2 * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights 3 * reserved. 4 * 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * * Neither the name of Cavium Networks nor the names of 19 * its contributors may be used to endorse or promote products 20 * derived from this software without specific prior written 21 * permission. 22 * 23 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 24 * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS 25 * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH 26 * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY 27 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT 28 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES 29 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR 30 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET 31 * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT 32 * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 33 * 34 * 35 * For any questions regarding licensing please contact marketing@caviumnetworks.com 36 * 37 ***********************license end**************************************/ 38 39/* 40 * octeon_ebt3000_cf.c 41 * 42 */ 43 44#include <sys/cdefs.h> 45__FBSDID("$FreeBSD: stable/11/sys/mips/cavium/octeon_ebt3000_cf.c 323201 2017-09-06 02:03:22Z emaste $"); 46 47#include <sys/param.h> 48#include <sys/bio.h> 49#include <sys/systm.h> 50#include <sys/sysctl.h> 51#include <sys/ata.h> 52#include <sys/bus.h> 53#include <sys/kernel.h> 54#include <sys/module.h> 55#include <sys/rman.h> 56#include <sys/power.h> 57#include <sys/smp.h> 58#include <sys/time.h> 59#include <sys/timetc.h> 60#include <sys/malloc.h> 61 62#include <geom/geom.h> 63 64#include <machine/clock.h> 65#include <machine/locore.h> 66#include <machine/md_var.h> 67#include <machine/cpuregs.h> 68 69#include <mips/cavium/octeon_pcmap_regs.h> 70 71#include <contrib/octeon-sdk/cvmx.h> 72 73/* ATA Commands */ 74#define CMD_READ_SECTOR 0x20 75#define CMD_WRITE_SECTOR 0x30 76#define CMD_IDENTIFY 0xEC 77 78/* The ATA Task File */ 79#define TF_DATA 0x00 80#define TF_ERROR 0x01 81#define TF_PRECOMP 0x01 82#define TF_SECTOR_COUNT 0x02 83#define TF_SECTOR_NUMBER 0x03 84#define TF_CYL_LSB 0x04 85#define TF_CYL_MSB 0x05 86#define TF_DRV_HEAD 0x06 87#define TF_STATUS 0x07 88#define TF_COMMAND 0x07 89 90/* Status Register */ 91#define STATUS_BSY 0x80 /* Drive is busy */ 92#define STATUS_RDY 0x40 /* Drive is ready */ 93#define STATUS_DF 0x20 /* Device fault */ 94#define STATUS_DRQ 0x08 /* Data can be transferred */ 95 96/* Miscelaneous */ 97#define SECTOR_SIZE 512 98#define WAIT_DELAY 1000 99#define NR_TRIES 1000 100#define SWAP_SHORT(x) ((x << 8) | (x >> 8)) 101#define MODEL_STR_SIZE 40 102 103/* Globals */ 104/* 105 * There's three bus types supported by this driver. 106 * 107 * CF_8 -- Traditional PC Card IDE interface on an 8-bit wide bus. We assume 108 * the bool loader has configure attribute memory properly. We then access 109 * the device like old-school 8-bit IDE card (which is all a traditional PC Card 110 * interface really is). 111 * CF_16 -- Traditional PC Card IDE interface on a 16-bit wide bus. Registers on 112 * this bus are 16-bits wide too. When accessing registers in the task file, you 113 * have to do it in 16-bit chunks, and worry about masking out what you don't want 114 * or ORing together the traditional 8-bit values. We assume the bootloader does 115 * the right attribute memory initialization dance. 116 * CF_TRUE_IDE_8 - CF Card wired to True IDE mode. There's no Attribute memory 117 * space at all. Instead all the traditional 8-bit registers are there, but 118 * on a 16-bit bus where addr0 isn't wired. This means we need to read/write them 119 * 16-bit chunks, but only the lower 8 bits are valid. We do not (and can not) 120 * access this like CF_16 with the comingled registers. Yet we can't access 121 * this like CF_8 because of the register offset. Except the TF_DATA register 122 * appears to be full width? 123 */ 124void *base_addr; 125int bus_type; 126#define CF_8 1 /* 8-bit bus, no offsets - PC Card */ 127#define CF_16 2 /* 16-bit bus, registers shared - PC Card */ 128#define CF_TRUE_IDE_8 3 /* 16-bit bus, only lower 8-bits, TrueIDE */ 129const char *const cf_type[] = { 130 "impossible type", 131 "CF 8-bit", 132 "CF 16-bit", 133 "True IDE" 134}; 135 136/* Device parameters */ 137struct drive_param{ 138 union { 139 char buf[SECTOR_SIZE]; 140 struct ata_params driveid; 141 } u; 142 143 char model[MODEL_STR_SIZE]; 144 uint32_t nr_sectors; 145 uint16_t sector_size; 146 uint16_t heads; 147 uint16_t tracks; 148 uint16_t sec_track; 149}; 150 151/* Device softc */ 152struct cf_priv { 153 device_t dev; 154 struct drive_param drive_param; 155 156 struct bio_queue_head cf_bq; 157 struct g_geom *cf_geom; 158 struct g_provider *cf_provider; 159 160}; 161 162/* GEOM class implementation */ 163static g_access_t cf_access; 164static g_start_t cf_start; 165static g_ioctl_t cf_ioctl; 166 167struct g_class g_cf_class = { 168 .name = "CF", 169 .version = G_VERSION, 170 .start = cf_start, 171 .access = cf_access, 172 .ioctl = cf_ioctl, 173}; 174 175DECLARE_GEOM_CLASS(g_cf_class, g_cf); 176 177/* Device methods */ 178static int cf_probe(device_t); 179static void cf_identify(driver_t *, device_t); 180static int cf_attach(device_t); 181static void cf_attach_geom(void *, int); 182 183/* ATA methods */ 184static int cf_cmd_identify(struct cf_priv *); 185static int cf_cmd_write(uint32_t, uint32_t, void *); 186static int cf_cmd_read(uint32_t, uint32_t, void *); 187static int cf_wait_busy(void); 188static int cf_send_cmd(uint32_t, uint8_t); 189 190/* Miscelenous */ 191static void cf_swap_ascii(unsigned char[], char[]); 192 193 194/* ------------------------------------------------------------------- * 195 * cf_access() * 196 * ------------------------------------------------------------------- */ 197static int cf_access (struct g_provider *pp, int r, int w, int e) 198{ 199 return (0); 200} 201 202 203/* ------------------------------------------------------------------- * 204 * cf_start() * 205 * ------------------------------------------------------------------- */ 206static void cf_start (struct bio *bp) 207{ 208 struct cf_priv *cf_priv; 209 int error; 210 211 cf_priv = bp->bio_to->geom->softc; 212 213 /* 214 * Handle actual I/O requests. The request is passed down through 215 * the bio struct. 216 */ 217 218 switch (bp->bio_cmd) { 219 case BIO_GETATTR: 220 if (g_handleattr_int(bp, "GEOM::fwsectors", cf_priv->drive_param.sec_track)) 221 return; 222 if (g_handleattr_int(bp, "GEOM::fwheads", cf_priv->drive_param.heads)) 223 return; 224 g_io_deliver(bp, ENOIOCTL); 225 return; 226 227 case BIO_READ: 228 error = cf_cmd_read(bp->bio_length / cf_priv->drive_param.sector_size, 229 bp->bio_offset / cf_priv->drive_param.sector_size, bp->bio_data); 230 break; 231 case BIO_WRITE: 232 error = cf_cmd_write(bp->bio_length / cf_priv->drive_param.sector_size, 233 bp->bio_offset/cf_priv->drive_param.sector_size, bp->bio_data); 234 break; 235 236 default: 237 printf("%s: unrecognized bio_cmd %x.\n", __func__, bp->bio_cmd); 238 error = ENOTSUP; 239 break; 240 } 241 242 if (error != 0) { 243 g_io_deliver(bp, error); 244 return; 245 } 246 247 bp->bio_resid = 0; 248 bp->bio_completed = bp->bio_length; 249 g_io_deliver(bp, 0); 250} 251 252 253static int cf_ioctl (struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td) 254{ 255 return (0); 256} 257 258 259static uint8_t cf_inb_8(int port) 260{ 261 /* 262 * Traditional 8-bit PC Card/CF bus access. 263 */ 264 if (bus_type == CF_8) { 265 volatile uint8_t *task_file = (volatile uint8_t *)base_addr; 266 return task_file[port]; 267 } 268 269 /* 270 * True IDE access. lower 8 bits on a 16-bit bus (see above). 271 */ 272 volatile uint16_t *task_file = (volatile uint16_t *)base_addr; 273 return task_file[port] & 0xff; 274} 275 276static void cf_outb_8(int port, uint8_t val) 277{ 278 /* 279 * Traditional 8-bit PC Card/CF bus access. 280 */ 281 if (bus_type == CF_8) { 282 volatile uint8_t *task_file = (volatile uint8_t *)base_addr; 283 task_file[port] = val; 284 return; 285 } 286 287 /* 288 * True IDE access. lower 8 bits on a 16-bit bus (see above). 289 */ 290 volatile uint16_t *task_file = (volatile uint16_t *)base_addr; 291 task_file[port] = val & 0xff; 292} 293 294static uint8_t cf_inb_16(int port) 295{ 296 volatile uint16_t *task_file = (volatile uint16_t *)base_addr; 297 uint16_t val = task_file[port / 2]; 298 if (port & 1) 299 return (val >> 8) & 0xff; 300 return val & 0xff; 301} 302 303static uint16_t cf_inw_16(int port) 304{ 305 volatile uint16_t *task_file = (volatile uint16_t *)base_addr; 306 uint16_t val = task_file[port / 2]; 307 return val; 308} 309 310static void cf_outw_16(int port, uint16_t val) 311{ 312 volatile uint16_t *task_file = (volatile uint16_t *)base_addr; 313 task_file[port / 2] = val; 314} 315 316/* ------------------------------------------------------------------- * 317 * cf_cmd_read() * 318 * ------------------------------------------------------------------- * 319 * 320 * Read nr_sectors from the device starting from start_sector. 321 */ 322static int cf_cmd_read (uint32_t nr_sectors, uint32_t start_sector, void *buf) 323{ 324 unsigned long lba; 325 uint32_t count; 326 uint16_t *ptr_16; 327 uint8_t *ptr_8; 328 int error; 329 330 ptr_8 = (uint8_t*)buf; 331 ptr_16 = (uint16_t*)buf; 332 lba = start_sector; 333 334 while (nr_sectors--) { 335 error = cf_send_cmd(lba, CMD_READ_SECTOR); 336 if (error != 0) { 337 printf("%s: cf_send_cmd(CMD_READ_SECTOR) failed: %d\n", __func__, error); 338 return (error); 339 } 340 341 switch (bus_type) 342 { 343 case CF_8: 344 for (count = 0; count < SECTOR_SIZE; count++) { 345 *ptr_8++ = cf_inb_8(TF_DATA); 346 if ((count & 0xf) == 0) 347 (void)cf_inb_8(TF_STATUS); 348 } 349 break; 350 case CF_TRUE_IDE_8: 351 case CF_16: 352 default: 353 for (count = 0; count < SECTOR_SIZE; count+=2) { 354 uint16_t temp; 355 temp = cf_inw_16(TF_DATA); 356 *ptr_16++ = SWAP_SHORT(temp); 357 if ((count & 0xf) == 0) 358 (void)cf_inb_16(TF_STATUS); 359 } 360 break; 361 } 362 363 lba++; 364 } 365 return (0); 366} 367 368 369/* ------------------------------------------------------------------- * 370 * cf_cmd_write() * 371 * ------------------------------------------------------------------- * 372 * 373 * Write nr_sectors to the device starting from start_sector. 374 */ 375static int cf_cmd_write (uint32_t nr_sectors, uint32_t start_sector, void *buf) 376{ 377 uint32_t lba; 378 uint32_t count; 379 uint16_t *ptr_16; 380 uint8_t *ptr_8; 381 int error; 382 383 lba = start_sector; 384 ptr_8 = (uint8_t*)buf; 385 ptr_16 = (uint16_t*)buf; 386 387 while (nr_sectors--) { 388 error = cf_send_cmd(lba, CMD_WRITE_SECTOR); 389 if (error != 0) { 390 printf("%s: cf_send_cmd(CMD_WRITE_SECTOR) failed: %d\n", __func__, error); 391 return (error); 392 } 393 394 switch (bus_type) 395 { 396 case CF_8: 397 for (count = 0; count < SECTOR_SIZE; count++) { 398 cf_outb_8(TF_DATA, *ptr_8++); 399 if ((count & 0xf) == 0) 400 (void)cf_inb_8(TF_STATUS); 401 } 402 break; 403 case CF_TRUE_IDE_8: 404 case CF_16: 405 default: 406 for (count = 0; count < SECTOR_SIZE; count+=2) { 407 uint16_t temp = *ptr_16++; 408 cf_outw_16(TF_DATA, SWAP_SHORT(temp)); 409 if ((count & 0xf) == 0) 410 (void)cf_inb_16(TF_STATUS); 411 } 412 break; 413 } 414 415 lba++; 416 } 417 return (0); 418} 419 420 421/* ------------------------------------------------------------------- * 422 * cf_cmd_identify() * 423 * ------------------------------------------------------------------- * 424 * 425 * Read parameters and other information from the drive and store 426 * it in the drive_param structure 427 * 428 */ 429static int cf_cmd_identify(struct cf_priv *cf_priv) 430{ 431 int count; 432 int error; 433 434 error = cf_send_cmd(0, CMD_IDENTIFY); 435 if (error != 0) { 436 printf("%s: identify failed: %d\n", __func__, error); 437 return (error); 438 } 439 switch (bus_type) 440 { 441 case CF_8: 442 for (count = 0; count < SECTOR_SIZE; count++) 443 cf_priv->drive_param.u.buf[count] = cf_inb_8(TF_DATA); 444 break; 445 case CF_TRUE_IDE_8: 446 case CF_16: 447 default: 448 for (count = 0; count < SECTOR_SIZE; count += 2) { 449 uint16_t temp; 450 temp = cf_inw_16(TF_DATA); 451 452 /* endianess will be swapped below */ 453 cf_priv->drive_param.u.buf[count] = (temp & 0xff); 454 cf_priv->drive_param.u.buf[count + 1] = (temp & 0xff00) >> 8; 455 } 456 break; 457 } 458 459 cf_swap_ascii(cf_priv->drive_param.u.driveid.model, cf_priv->drive_param.model); 460 461 cf_priv->drive_param.sector_size = 512; //= SWAP_SHORT (cf_priv->drive_param.u.driveid.sector_bytes); 462 cf_priv->drive_param.heads = SWAP_SHORT (cf_priv->drive_param.u.driveid.current_heads); 463 cf_priv->drive_param.tracks = SWAP_SHORT (cf_priv->drive_param.u.driveid.current_cylinders); 464 cf_priv->drive_param.sec_track = SWAP_SHORT (cf_priv->drive_param.u.driveid.current_sectors); 465 cf_priv->drive_param.nr_sectors = (uint32_t)SWAP_SHORT (cf_priv->drive_param.u.driveid.lba_size_1) | 466 ((uint32_t)SWAP_SHORT (cf_priv->drive_param.u.driveid.lba_size_2)); 467 if (bootverbose) { 468 printf(" model %s\n", cf_priv->drive_param.model); 469 printf(" heads %d tracks %d sec_tracks %d sectors %d\n", 470 cf_priv->drive_param.heads, cf_priv->drive_param.tracks, 471 cf_priv->drive_param.sec_track, cf_priv->drive_param.nr_sectors); 472 } 473 474 return (0); 475} 476 477 478/* ------------------------------------------------------------------- * 479 * cf_send_cmd() * 480 * ------------------------------------------------------------------- * 481 * 482 * Send command to read/write one sector specified by lba. 483 * 484 */ 485static int cf_send_cmd (uint32_t lba, uint8_t cmd) 486{ 487 switch (bus_type) 488 { 489 case CF_8: 490 case CF_TRUE_IDE_8: 491 while (cf_inb_8(TF_STATUS) & STATUS_BSY) 492 DELAY(WAIT_DELAY); 493 cf_outb_8(TF_SECTOR_COUNT, 1); 494 cf_outb_8(TF_SECTOR_NUMBER, lba & 0xff); 495 cf_outb_8(TF_CYL_LSB, (lba >> 8) & 0xff); 496 cf_outb_8(TF_CYL_MSB, (lba >> 16) & 0xff); 497 cf_outb_8(TF_DRV_HEAD, ((lba >> 24) & 0xff) | 0xe0); 498 cf_outb_8(TF_COMMAND, cmd); 499 break; 500 case CF_16: 501 default: 502 while (cf_inb_16(TF_STATUS) & STATUS_BSY) 503 DELAY(WAIT_DELAY); 504 cf_outw_16(TF_SECTOR_COUNT, 1 | ((lba & 0xff) << 8)); 505 cf_outw_16(TF_CYL_LSB, ((lba >> 8) & 0xff) | (((lba >> 16) & 0xff) << 8)); 506 cf_outw_16(TF_DRV_HEAD, (((lba >> 24) & 0xff) | 0xe0) | (cmd << 8)); 507 break; 508 } 509 510 return (cf_wait_busy()); 511} 512 513/* ------------------------------------------------------------------- * 514 * cf_wait_busy() * 515 * ------------------------------------------------------------------- * 516 * 517 * Wait until the drive finishes a given command and data is 518 * ready to be transferred. This is done by repeatedly checking 519 * the BSY bit of the status register. When the controller is ready for 520 * data transfer, it clears the BSY bit and sets the DRQ bit. 521 * 522 * If the DF bit is ever set, we return error. 523 * 524 * This code originally spun on DRQ. If that behavior turns out to be 525 * necessary, a flag can be added or this function can be called 526 * repeatedly as long as it is returning ENXIO. 527 */ 528static int cf_wait_busy (void) 529{ 530 uint8_t status; 531 532 switch (bus_type) 533 { 534 case CF_8: 535 case CF_TRUE_IDE_8: 536 status = cf_inb_8(TF_STATUS); 537 while ((status & STATUS_BSY) == STATUS_BSY) { 538 if ((status & STATUS_DF) != 0) { 539 printf("%s: device fault (status=%x)\n", __func__, status); 540 return (EIO); 541 } 542 DELAY(WAIT_DELAY); 543 status = cf_inb_8(TF_STATUS); 544 } 545 break; 546 case CF_16: 547 default: 548 status = cf_inb_16(TF_STATUS); 549 while ((status & STATUS_BSY) == STATUS_BSY) { 550 if ((status & STATUS_DF) != 0) { 551 printf("%s: device fault (status=%x)\n", __func__, status); 552 return (EIO); 553 } 554 DELAY(WAIT_DELAY); 555 status = cf_inb_16(TF_STATUS); 556 } 557 break; 558 } 559 560 /* DRQ is only for when read data is actually available; check BSY */ 561 /* Some vendors do assert DRQ, but not all. Check BSY instead. */ 562 if (status & STATUS_BSY) { 563 printf("%s: device not ready (status=%x)\n", __func__, status); 564 return (ENXIO); 565 } 566 567 return (0); 568} 569 570/* ------------------------------------------------------------------- * 571 * cf_swap_ascii() * 572 * ------------------------------------------------------------------- * 573 * 574 * The ascii string returned by the controller specifying 575 * the model of the drive is byte-swaped. This routine 576 * corrects the byte ordering. 577 * 578 */ 579static void cf_swap_ascii (unsigned char str1[], char str2[]) 580{ 581 int i; 582 583 for(i = 0; i < MODEL_STR_SIZE; i++) 584 str2[i] = str1[i ^ 1]; 585} 586 587 588/* ------------------------------------------------------------------- * 589 * cf_probe() * 590 * ------------------------------------------------------------------- */ 591 592static int cf_probe (device_t dev) 593{ 594 if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) 595 return (ENXIO); 596 597 if (device_get_unit(dev) != 0) { 598 panic("can't attach more devices\n"); 599 } 600 601 device_set_desc(dev, "Octeon Compact Flash Driver"); 602 603 return (BUS_PROBE_NOWILDCARD); 604} 605 606/* ------------------------------------------------------------------- * 607 * cf_identify() * 608 * ------------------------------------------------------------------- * 609 * 610 * Find the bootbus region for the CF to determine 611 * 16 or 8 bit and check to see if device is 612 * inserted. 613 * 614 */ 615static void cf_identify (driver_t *drv, device_t parent) 616{ 617 int bus_region; 618 int count = 0; 619 cvmx_mio_boot_reg_cfgx_t cfg; 620 uint64_t phys_base; 621 622 if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) 623 return; 624 625 phys_base = cvmx_sysinfo_get()->compact_flash_common_base_addr; 626 if (phys_base == 0) 627 return; 628 base_addr = cvmx_phys_to_ptr(phys_base); 629 630 for (bus_region = 0; bus_region < 8; bus_region++) 631 { 632 cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(bus_region)); 633 if (cfg.s.base == phys_base >> 16) 634 { 635 if (cvmx_sysinfo_get()->compact_flash_attribute_base_addr == 0) 636 bus_type = CF_TRUE_IDE_8; 637 else 638 bus_type = (cfg.s.width) ? CF_16 : CF_8; 639 printf("Compact flash found in bootbus region %d (%s).\n", bus_region, cf_type[bus_type]); 640 break; 641 } 642 } 643 644 switch (bus_type) 645 { 646 case CF_8: 647 case CF_TRUE_IDE_8: 648 /* Check if CF is inserted */ 649 while (cf_inb_8(TF_STATUS) & STATUS_BSY) { 650 if ((count++) == NR_TRIES ) { 651 printf("Compact Flash not present\n"); 652 return; 653 } 654 DELAY(WAIT_DELAY); 655 } 656 break; 657 case CF_16: 658 default: 659 /* Check if CF is inserted */ 660 while (cf_inb_16(TF_STATUS) & STATUS_BSY) { 661 if ((count++) == NR_TRIES ) { 662 printf("Compact Flash not present\n"); 663 return; 664 } 665 DELAY(WAIT_DELAY); 666 } 667 break; 668 } 669 670 BUS_ADD_CHILD(parent, 0, "cf", 0); 671} 672 673 674/* ------------------------------------------------------------------- * 675 * cf_attach_geom() * 676 * ------------------------------------------------------------------- */ 677 678static void cf_attach_geom (void *arg, int flag) 679{ 680 struct cf_priv *cf_priv; 681 682 cf_priv = (struct cf_priv *) arg; 683 cf_priv->cf_geom = g_new_geomf(&g_cf_class, "cf%d", device_get_unit(cf_priv->dev)); 684 cf_priv->cf_geom->softc = cf_priv; 685 cf_priv->cf_provider = g_new_providerf(cf_priv->cf_geom, "%s", 686 cf_priv->cf_geom->name); 687 cf_priv->cf_provider->sectorsize = cf_priv->drive_param.sector_size; 688 cf_priv->cf_provider->mediasize = cf_priv->drive_param.nr_sectors * cf_priv->cf_provider->sectorsize; 689 g_error_provider(cf_priv->cf_provider, 0); 690} 691 692/* ------------------------------------------------------------------- * 693 * cf_attach() * 694 * ------------------------------------------------------------------- */ 695 696static int cf_attach (device_t dev) 697{ 698 struct cf_priv *cf_priv; 699 int error; 700 701 if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) 702 return (ENXIO); 703 704 cf_priv = device_get_softc(dev); 705 cf_priv->dev = dev; 706 707 error = cf_cmd_identify(cf_priv); 708 if (error != 0) { 709 device_printf(dev, "cf_cmd_identify failed: %d\n", error); 710 return (error); 711 } 712 713 g_post_event(cf_attach_geom, cf_priv, M_WAITOK, NULL); 714 bioq_init(&cf_priv->cf_bq); 715 716 return 0; 717} 718 719 720static device_method_t cf_methods[] = { 721 /* Device interface */ 722 DEVMETHOD(device_probe, cf_probe), 723 DEVMETHOD(device_identify, cf_identify), 724 DEVMETHOD(device_attach, cf_attach), 725 DEVMETHOD(device_detach, bus_generic_detach), 726 DEVMETHOD(device_shutdown, bus_generic_shutdown), 727 728 { 0, 0 } 729}; 730 731static driver_t cf_driver = { 732 "cf", 733 cf_methods, 734 sizeof(struct cf_priv) 735}; 736 737static devclass_t cf_devclass; 738 739DRIVER_MODULE(cf, nexus, cf_driver, cf_devclass, 0, 0); 740