1 /********************************************************************** 2 * Author: Cavium, Inc. 3 * 4 * Contact: support@cavium.com 5 * Please include "LiquidIO" in the subject. 6 * 7 * Copyright (c) 2003-2015 Cavium, Inc. 8 * 9 * This file is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License, Version 2, as 11 * published by the Free Software Foundation. 12 * 13 * This file is distributed in the hope that it will be useful, but 14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 16 * NONINFRINGEMENT. See the GNU General Public License for more 17 * details. 18 * 19 * This file may also be available under a different license from Cavium. 20 * Contact Cavium, Inc. for more information 21 **********************************************************************/ 22 23 /** 24 * @file octeon_console.c 25 */ 26 #include <linux/pci.h> 27 #include <linux/netdevice.h> 28 #include "liquidio_common.h" 29 #include "octeon_droq.h" 30 #include "octeon_iq.h" 31 #include "response_manager.h" 32 #include "octeon_device.h" 33 #include "octeon_main.h" 34 #include "octeon_mem_ops.h" 35 36 static void octeon_remote_lock(void); 37 static void octeon_remote_unlock(void); 38 static u64 cvmx_bootmem_phy_named_block_find(struct octeon_device *oct, 39 const char *name, 40 u32 flags); 41 static int octeon_console_read(struct octeon_device *oct, u32 console_num, 42 char *buffer, u32 buf_size); 43 44 #define MIN(a, b) min((a), (b)) 45 #define CAST_ULL(v) ((u64)(v)) 46 47 #define BOOTLOADER_PCI_READ_BUFFER_DATA_ADDR 0x0006c008 48 #define BOOTLOADER_PCI_READ_BUFFER_LEN_ADDR 0x0006c004 49 #define BOOTLOADER_PCI_READ_BUFFER_OWNER_ADDR 0x0006c000 50 #define BOOTLOADER_PCI_READ_DESC_ADDR 0x0006c100 51 #define BOOTLOADER_PCI_WRITE_BUFFER_STR_LEN 248 52 53 #define OCTEON_PCI_IO_BUF_OWNER_OCTEON 0x00000001 54 #define OCTEON_PCI_IO_BUF_OWNER_HOST 0x00000002 55 56 /** Can change without breaking ABI */ 57 #define CVMX_BOOTMEM_NUM_NAMED_BLOCKS 64 58 59 /** minimum alignment of bootmem alloced blocks */ 60 #define CVMX_BOOTMEM_ALIGNMENT_SIZE (16ull) 61 62 /** CVMX bootmem descriptor major version */ 63 #define CVMX_BOOTMEM_DESC_MAJ_VER 3 64 /* CVMX bootmem descriptor minor version */ 65 #define CVMX_BOOTMEM_DESC_MIN_VER 0 66 67 /* Current versions */ 68 #define OCTEON_PCI_CONSOLE_MAJOR_VERSION 1 69 #define OCTEON_PCI_CONSOLE_MINOR_VERSION 0 70 #define OCTEON_PCI_CONSOLE_BLOCK_NAME "__pci_console" 71 #define OCTEON_CONSOLE_POLL_INTERVAL_MS 100 /* 10 times per second */ 72 73 /* First three members of cvmx_bootmem_desc are left in original 74 ** positions for backwards compatibility. 75 ** Assumes big endian target 76 */ 77 struct cvmx_bootmem_desc { 78 /** spinlock to control access to list */ 79 u32 lock; 80 81 /** flags for indicating various conditions */ 82 u32 flags; 83 84 u64 head_addr; 85 86 /** incremented changed when incompatible changes made */ 87 u32 major_version; 88 89 /** incremented changed when compatible changes made, 90 * reset to zero when major incremented 91 */ 92 u32 minor_version; 93 94 u64 app_data_addr; 95 u64 app_data_size; 96 97 /** number of elements in named blocks array */ 98 u32 nb_num_blocks; 99 100 /** length of name array in bootmem blocks */ 101 u32 named_block_name_len; 102 103 /** address of named memory block descriptors */ 104 u64 named_block_array_addr; 105 }; 106 107 /* Structure that defines a single console. 108 * 109 * Note: when read_index == write_index, the buffer is empty. 110 * The actual usable size of each console is console_buf_size -1; 111 */ 112 struct octeon_pci_console { 113 u64 input_base_addr; 114 u32 input_read_index; 115 u32 input_write_index; 116 u64 output_base_addr; 117 u32 output_read_index; 118 u32 output_write_index; 119 u32 lock; 120 u32 buf_size; 121 }; 122 123 /* This is the main container structure that contains all the information 124 * about all PCI consoles. The address of this structure is passed to various 125 * routines that operation on PCI consoles. 126 */ 127 struct octeon_pci_console_desc { 128 u32 major_version; 129 u32 minor_version; 130 u32 lock; 131 u32 flags; 132 u32 num_consoles; 133 u32 pad; 134 /* must be 64 bit aligned here... */ 135 /* Array of addresses of octeon_pci_console structures */ 136 u64 console_addr_array[0]; 137 /* Implicit storage for console_addr_array */ 138 }; 139 140 /** 141 * This macro returns the size of a member of a structure. 142 * Logically it is the same as "sizeof(s::field)" in C++, but 143 * C lacks the "::" operator. 144 */ 145 #define SIZEOF_FIELD(s, field) sizeof(((s *)NULL)->field) 146 147 /** 148 * This macro returns a member of the cvmx_bootmem_desc 149 * structure. These members can't be directly addressed as 150 * they might be in memory not directly reachable. In the case 151 * where bootmem is compiled with LINUX_HOST, the structure 152 * itself might be located on a remote Octeon. The argument 153 * "field" is the member name of the cvmx_bootmem_desc to read. 154 * Regardless of the type of the field, the return type is always 155 * a u64. 156 */ 157 #define CVMX_BOOTMEM_DESC_GET_FIELD(oct, field) \ 158 __cvmx_bootmem_desc_get(oct, oct->bootmem_desc_addr, \ 159 offsetof(struct cvmx_bootmem_desc, field), \ 160 SIZEOF_FIELD(struct cvmx_bootmem_desc, field)) 161 162 #define __cvmx_bootmem_lock(flags) (flags = flags) 163 #define __cvmx_bootmem_unlock(flags) (flags = flags) 164 165 /** 166 * This macro returns a member of the 167 * cvmx_bootmem_named_block_desc structure. These members can't 168 * be directly addressed as they might be in memory not directly 169 * reachable. In the case where bootmem is compiled with 170 * LINUX_HOST, the structure itself might be located on a remote 171 * Octeon. The argument "field" is the member name of the 172 * cvmx_bootmem_named_block_desc to read. Regardless of the type 173 * of the field, the return type is always a u64. The "addr" 174 * parameter is the physical address of the structure. 175 */ 176 #define CVMX_BOOTMEM_NAMED_GET_FIELD(oct, addr, field) \ 177 __cvmx_bootmem_desc_get(oct, addr, \ 178 offsetof(struct cvmx_bootmem_named_block_desc, field), \ 179 SIZEOF_FIELD(struct cvmx_bootmem_named_block_desc, field)) 180 181 /** 182 * This function is the implementation of the get macros defined 183 * for individual structure members. The argument are generated 184 * by the macros inorder to read only the needed memory. 185 * 186 * @param oct Pointer to current octeon device 187 * @param base 64bit physical address of the complete structure 188 * @param offset Offset from the beginning of the structure to the member being 189 * accessed. 190 * @param size Size of the structure member. 191 * 192 * @return Value of the structure member promoted into a u64. 193 */ 194 static inline u64 __cvmx_bootmem_desc_get(struct octeon_device *oct, 195 u64 base, 196 u32 offset, 197 u32 size) 198 { 199 base = (1ull << 63) | (base + offset); 200 switch (size) { 201 case 4: 202 return octeon_read_device_mem32(oct, base); 203 case 8: 204 return octeon_read_device_mem64(oct, base); 205 default: 206 return 0; 207 } 208 } 209 210 /** 211 * This function retrieves the string name of a named block. It is 212 * more complicated than a simple memcpy() since the named block 213 * descriptor may not be directly accessible. 214 * 215 * @param addr Physical address of the named block descriptor 216 * @param str String to receive the named block string name 217 * @param len Length of the string buffer, which must match the length 218 * stored in the bootmem descriptor. 219 */ 220 static void CVMX_BOOTMEM_NAMED_GET_NAME(struct octeon_device *oct, 221 u64 addr, 222 char *str, 223 u32 len) 224 { 225 addr += offsetof(struct cvmx_bootmem_named_block_desc, name); 226 octeon_pci_read_core_mem(oct, addr, (u8 *)str, len); 227 str[len] = 0; 228 } 229 230 /* See header file for descriptions of functions */ 231 232 /** 233 * Check the version information on the bootmem descriptor 234 * 235 * @param exact_match 236 * Exact major version to check against. A zero means 237 * check that the version supports named blocks. 238 * 239 * @return Zero if the version is correct. Negative if the version is 240 * incorrect. Failures also cause a message to be displayed. 241 */ 242 static int __cvmx_bootmem_check_version(struct octeon_device *oct, 243 u32 exact_match) 244 { 245 u32 major_version; 246 u32 minor_version; 247 248 if (!oct->bootmem_desc_addr) 249 oct->bootmem_desc_addr = 250 octeon_read_device_mem64(oct, 251 BOOTLOADER_PCI_READ_DESC_ADDR); 252 major_version = 253 (u32)CVMX_BOOTMEM_DESC_GET_FIELD(oct, major_version); 254 minor_version = 255 (u32)CVMX_BOOTMEM_DESC_GET_FIELD(oct, minor_version); 256 dev_dbg(&oct->pci_dev->dev, "%s: major_version=%d\n", __func__, 257 major_version); 258 if ((major_version > 3) || 259 (exact_match && major_version != exact_match)) { 260 dev_err(&oct->pci_dev->dev, "bootmem ver mismatch %d.%d addr:0x%llx\n", 261 major_version, minor_version, 262 CAST_ULL(oct->bootmem_desc_addr)); 263 return -1; 264 } else { 265 return 0; 266 } 267 } 268 269 static const struct cvmx_bootmem_named_block_desc 270 *__cvmx_bootmem_find_named_block_flags(struct octeon_device *oct, 271 const char *name, u32 flags) 272 { 273 struct cvmx_bootmem_named_block_desc *desc = 274 &oct->bootmem_named_block_desc; 275 u64 named_addr = cvmx_bootmem_phy_named_block_find(oct, name, flags); 276 277 if (named_addr) { 278 desc->base_addr = CVMX_BOOTMEM_NAMED_GET_FIELD(oct, named_addr, 279 base_addr); 280 desc->size = 281 CVMX_BOOTMEM_NAMED_GET_FIELD(oct, named_addr, size); 282 strncpy(desc->name, name, sizeof(desc->name)); 283 desc->name[sizeof(desc->name) - 1] = 0; 284 return &oct->bootmem_named_block_desc; 285 } else { 286 return NULL; 287 } 288 } 289 290 static u64 cvmx_bootmem_phy_named_block_find(struct octeon_device *oct, 291 const char *name, 292 u32 flags) 293 { 294 u64 result = 0; 295 296 __cvmx_bootmem_lock(flags); 297 if (!__cvmx_bootmem_check_version(oct, 3)) { 298 u32 i; 299 u64 named_block_array_addr = 300 CVMX_BOOTMEM_DESC_GET_FIELD(oct, 301 named_block_array_addr); 302 u32 num_blocks = (u32) 303 CVMX_BOOTMEM_DESC_GET_FIELD(oct, nb_num_blocks); 304 u32 name_length = (u32) 305 CVMX_BOOTMEM_DESC_GET_FIELD(oct, named_block_name_len); 306 u64 named_addr = named_block_array_addr; 307 308 for (i = 0; i < num_blocks; i++) { 309 u64 named_size = 310 CVMX_BOOTMEM_NAMED_GET_FIELD(oct, named_addr, 311 size); 312 if (name && named_size) { 313 char *name_tmp = 314 kmalloc(name_length + 1, GFP_KERNEL); 315 if (!name_tmp) 316 break; 317 318 CVMX_BOOTMEM_NAMED_GET_NAME(oct, named_addr, 319 name_tmp, 320 name_length); 321 if (!strncmp(name, name_tmp, name_length)) { 322 result = named_addr; 323 kfree(name_tmp); 324 break; 325 } 326 kfree(name_tmp); 327 } else if (!name && !named_size) { 328 result = named_addr; 329 break; 330 } 331 332 named_addr += 333 sizeof(struct cvmx_bootmem_named_block_desc); 334 } 335 } 336 __cvmx_bootmem_unlock(flags); 337 return result; 338 } 339 340 /** 341 * Find a named block on the remote Octeon 342 * 343 * @param name Name of block to find 344 * @param base_addr Address the block is at (OUTPUT) 345 * @param size The size of the block (OUTPUT) 346 * 347 * @return Zero on success, One on failure. 348 */ 349 static int octeon_named_block_find(struct octeon_device *oct, const char *name, 350 u64 *base_addr, u64 *size) 351 { 352 const struct cvmx_bootmem_named_block_desc *named_block; 353 354 octeon_remote_lock(); 355 named_block = __cvmx_bootmem_find_named_block_flags(oct, name, 0); 356 octeon_remote_unlock(); 357 if (named_block) { 358 *base_addr = named_block->base_addr; 359 *size = named_block->size; 360 return 0; 361 } 362 return 1; 363 } 364 365 static void octeon_remote_lock(void) 366 { 367 /* fill this in if any sharing is needed */ 368 } 369 370 static void octeon_remote_unlock(void) 371 { 372 /* fill this in if any sharing is needed */ 373 } 374 375 int octeon_console_send_cmd(struct octeon_device *oct, char *cmd_str, 376 u32 wait_hundredths) 377 { 378 u32 len = (u32)strlen(cmd_str); 379 380 dev_dbg(&oct->pci_dev->dev, "sending \"%s\" to bootloader\n", cmd_str); 381 382 if (len > BOOTLOADER_PCI_WRITE_BUFFER_STR_LEN - 1) { 383 dev_err(&oct->pci_dev->dev, "Command string too long, max length is: %d\n", 384 BOOTLOADER_PCI_WRITE_BUFFER_STR_LEN - 1); 385 return -1; 386 } 387 388 if (octeon_wait_for_bootloader(oct, wait_hundredths) != 0) { 389 dev_err(&oct->pci_dev->dev, "Bootloader not ready for command.\n"); 390 return -1; 391 } 392 393 /* Write command to bootloader */ 394 octeon_remote_lock(); 395 octeon_pci_write_core_mem(oct, BOOTLOADER_PCI_READ_BUFFER_DATA_ADDR, 396 (u8 *)cmd_str, len); 397 octeon_write_device_mem32(oct, BOOTLOADER_PCI_READ_BUFFER_LEN_ADDR, 398 len); 399 octeon_write_device_mem32(oct, BOOTLOADER_PCI_READ_BUFFER_OWNER_ADDR, 400 OCTEON_PCI_IO_BUF_OWNER_OCTEON); 401 402 /* Bootloader should accept command very quickly 403 * if it really was ready 404 */ 405 if (octeon_wait_for_bootloader(oct, 200) != 0) { 406 octeon_remote_unlock(); 407 dev_err(&oct->pci_dev->dev, "Bootloader did not accept command.\n"); 408 return -1; 409 } 410 octeon_remote_unlock(); 411 return 0; 412 } 413 414 int octeon_wait_for_bootloader(struct octeon_device *oct, 415 u32 wait_time_hundredths) 416 { 417 dev_dbg(&oct->pci_dev->dev, "waiting %d0 ms for bootloader\n", 418 wait_time_hundredths); 419 420 if (octeon_mem_access_ok(oct)) 421 return -1; 422 423 while (wait_time_hundredths > 0 && 424 octeon_read_device_mem32(oct, 425 BOOTLOADER_PCI_READ_BUFFER_OWNER_ADDR) 426 != OCTEON_PCI_IO_BUF_OWNER_HOST) { 427 if (--wait_time_hundredths <= 0) 428 return -1; 429 schedule_timeout_uninterruptible(HZ / 100); 430 } 431 return 0; 432 } 433 434 static void octeon_console_handle_result(struct octeon_device *oct, 435 size_t console_num) 436 { 437 struct octeon_console *console; 438 439 console = &oct->console[console_num]; 440 441 console->waiting = 0; 442 } 443 444 static char console_buffer[OCTEON_CONSOLE_MAX_READ_BYTES]; 445 446 static void output_console_line(struct octeon_device *oct, 447 struct octeon_console *console, 448 size_t console_num, 449 char *console_buffer, 450 s32 bytes_read) 451 { 452 char *line; 453 s32 i; 454 455 line = console_buffer; 456 for (i = 0; i < bytes_read; i++) { 457 /* Output a line at a time, prefixed */ 458 if (console_buffer[i] == '\n') { 459 console_buffer[i] = '\0'; 460 if (console->leftover[0]) { 461 dev_info(&oct->pci_dev->dev, "%lu: %s%s\n", 462 console_num, console->leftover, 463 line); 464 console->leftover[0] = '\0'; 465 } else { 466 dev_info(&oct->pci_dev->dev, "%lu: %s\n", 467 console_num, line); 468 } 469 line = &console_buffer[i + 1]; 470 } 471 } 472 473 /* Save off any leftovers */ 474 if (line != &console_buffer[bytes_read]) { 475 console_buffer[bytes_read] = '\0'; 476 strcpy(console->leftover, line); 477 } 478 } 479 480 static void check_console(struct work_struct *work) 481 { 482 s32 bytes_read, tries, total_read; 483 struct octeon_console *console; 484 struct cavium_wk *wk = (struct cavium_wk *)work; 485 struct octeon_device *oct = (struct octeon_device *)wk->ctxptr; 486 u32 console_num = (u32)wk->ctxul; 487 u32 delay; 488 489 console = &oct->console[console_num]; 490 tries = 0; 491 total_read = 0; 492 493 do { 494 /* Take console output regardless of whether it will 495 * be logged 496 */ 497 bytes_read = 498 octeon_console_read(oct, console_num, console_buffer, 499 sizeof(console_buffer) - 1); 500 if (bytes_read > 0) { 501 total_read += bytes_read; 502 if (console->waiting) 503 octeon_console_handle_result(oct, console_num); 504 if (octeon_console_debug_enabled(console_num)) { 505 output_console_line(oct, console, console_num, 506 console_buffer, bytes_read); 507 } 508 } else if (bytes_read < 0) { 509 dev_err(&oct->pci_dev->dev, "Error reading console %u, ret=%d\n", 510 console_num, bytes_read); 511 } 512 513 tries++; 514 } while ((bytes_read > 0) && (tries < 16)); 515 516 /* If nothing is read after polling the console, 517 * output any leftovers if any 518 */ 519 if (octeon_console_debug_enabled(console_num) && 520 (total_read == 0) && (console->leftover[0])) { 521 dev_info(&oct->pci_dev->dev, "%u: %s\n", 522 console_num, console->leftover); 523 console->leftover[0] = '\0'; 524 } 525 526 delay = OCTEON_CONSOLE_POLL_INTERVAL_MS; 527 528 schedule_delayed_work(&wk->work, msecs_to_jiffies(delay)); 529 } 530 531 int octeon_init_consoles(struct octeon_device *oct) 532 { 533 int ret = 0; 534 u64 addr, size; 535 536 ret = octeon_mem_access_ok(oct); 537 if (ret) { 538 dev_err(&oct->pci_dev->dev, "Memory access not okay'\n"); 539 return ret; 540 } 541 542 ret = octeon_named_block_find(oct, OCTEON_PCI_CONSOLE_BLOCK_NAME, &addr, 543 &size); 544 if (ret) { 545 dev_err(&oct->pci_dev->dev, "Could not find console '%s'\n", 546 OCTEON_PCI_CONSOLE_BLOCK_NAME); 547 return ret; 548 } 549 550 /* num_consoles > 0, is an indication that the consoles 551 * are accessible 552 */ 553 oct->num_consoles = octeon_read_device_mem32(oct, 554 addr + offsetof(struct octeon_pci_console_desc, 555 num_consoles)); 556 oct->console_desc_addr = addr; 557 558 dev_dbg(&oct->pci_dev->dev, "Initialized consoles. %d available\n", 559 oct->num_consoles); 560 561 return ret; 562 } 563 564 int octeon_add_console(struct octeon_device *oct, u32 console_num) 565 { 566 int ret = 0; 567 u32 delay; 568 u64 coreaddr; 569 struct delayed_work *work; 570 struct octeon_console *console; 571 572 if (console_num >= oct->num_consoles) { 573 dev_err(&oct->pci_dev->dev, 574 "trying to read from console number %d when only 0 to %d exist\n", 575 console_num, oct->num_consoles); 576 } else { 577 console = &oct->console[console_num]; 578 579 console->waiting = 0; 580 581 coreaddr = oct->console_desc_addr + console_num * 8 + 582 offsetof(struct octeon_pci_console_desc, 583 console_addr_array); 584 console->addr = octeon_read_device_mem64(oct, coreaddr); 585 coreaddr = console->addr + offsetof(struct octeon_pci_console, 586 buf_size); 587 console->buffer_size = octeon_read_device_mem32(oct, coreaddr); 588 coreaddr = console->addr + offsetof(struct octeon_pci_console, 589 input_base_addr); 590 console->input_base_addr = 591 octeon_read_device_mem64(oct, coreaddr); 592 coreaddr = console->addr + offsetof(struct octeon_pci_console, 593 output_base_addr); 594 console->output_base_addr = 595 octeon_read_device_mem64(oct, coreaddr); 596 console->leftover[0] = '\0'; 597 598 work = &oct->console_poll_work[console_num].work; 599 600 INIT_DELAYED_WORK(work, check_console); 601 oct->console_poll_work[console_num].ctxptr = (void *)oct; 602 oct->console_poll_work[console_num].ctxul = console_num; 603 delay = OCTEON_CONSOLE_POLL_INTERVAL_MS; 604 schedule_delayed_work(work, msecs_to_jiffies(delay)); 605 606 if (octeon_console_debug_enabled(console_num)) { 607 ret = octeon_console_send_cmd(oct, 608 "setenv pci_console_active 1", 609 2000); 610 } 611 612 console->active = 1; 613 } 614 615 return ret; 616 } 617 618 /** 619 * Removes all consoles 620 * 621 * @param oct octeon device 622 */ 623 void octeon_remove_consoles(struct octeon_device *oct) 624 { 625 u32 i; 626 struct octeon_console *console; 627 628 for (i = 0; i < oct->num_consoles; i++) { 629 console = &oct->console[i]; 630 631 if (!console->active) 632 continue; 633 634 cancel_delayed_work_sync(&oct->console_poll_work[i]. 635 work); 636 console->addr = 0; 637 console->buffer_size = 0; 638 console->input_base_addr = 0; 639 console->output_base_addr = 0; 640 } 641 642 oct->num_consoles = 0; 643 } 644 645 static inline int octeon_console_free_bytes(u32 buffer_size, 646 u32 wr_idx, 647 u32 rd_idx) 648 { 649 if (rd_idx >= buffer_size || wr_idx >= buffer_size) 650 return -1; 651 652 return ((buffer_size - 1) - (wr_idx - rd_idx)) % buffer_size; 653 } 654 655 static inline int octeon_console_avail_bytes(u32 buffer_size, 656 u32 wr_idx, 657 u32 rd_idx) 658 { 659 if (rd_idx >= buffer_size || wr_idx >= buffer_size) 660 return -1; 661 662 return buffer_size - 1 - 663 octeon_console_free_bytes(buffer_size, wr_idx, rd_idx); 664 } 665 666 static int octeon_console_read(struct octeon_device *oct, u32 console_num, 667 char *buffer, u32 buf_size) 668 { 669 int bytes_to_read; 670 u32 rd_idx, wr_idx; 671 struct octeon_console *console; 672 673 if (console_num >= oct->num_consoles) { 674 dev_err(&oct->pci_dev->dev, "Attempted to read from disabled console %d\n", 675 console_num); 676 return 0; 677 } 678 679 console = &oct->console[console_num]; 680 681 /* Check to see if any data is available. 682 * Maybe optimize this with 64-bit read. 683 */ 684 rd_idx = octeon_read_device_mem32(oct, console->addr + 685 offsetof(struct octeon_pci_console, output_read_index)); 686 wr_idx = octeon_read_device_mem32(oct, console->addr + 687 offsetof(struct octeon_pci_console, output_write_index)); 688 689 bytes_to_read = octeon_console_avail_bytes(console->buffer_size, 690 wr_idx, rd_idx); 691 if (bytes_to_read <= 0) 692 return bytes_to_read; 693 694 bytes_to_read = MIN(bytes_to_read, (s32)buf_size); 695 696 /* Check to see if what we want to read is not contiguous, and limit 697 * ourselves to the contiguous block 698 */ 699 if (rd_idx + bytes_to_read >= console->buffer_size) 700 bytes_to_read = console->buffer_size - rd_idx; 701 702 octeon_pci_read_core_mem(oct, console->output_base_addr + rd_idx, 703 (u8 *)buffer, bytes_to_read); 704 octeon_write_device_mem32(oct, console->addr + 705 offsetof(struct octeon_pci_console, 706 output_read_index), 707 (rd_idx + bytes_to_read) % 708 console->buffer_size); 709 710 return bytes_to_read; 711 } 712