/* * platform_configure_usb - usb configuration based on platform type. * @bcm1_usb2_ctl: value for the BCM1_USB2_CTL register, which is * quirky */ static void __init platform_configure_usb(void) { u32 bcm1_usb2_ctl; if (usb_configured) return; switch (asic) { case ASIC_ZEUS: case ASIC_CRONUS: case ASIC_CRONUSLITE: fs_update(0x0000, 0x11, 0x02, 0); bcm1_usb2_ctl = 0x803; break; case ASIC_CALLIOPE: fs_update(0x0000, 0x11, 0x02, 1); switch (platform_family) { case FAMILY_1500VZE: break; case FAMILY_1500VZF: usb_eye_configure(0x003c0000); break; default: usb_eye_configure(0x00300000); break; } bcm1_usb2_ctl = 0x803; break; default: pr_err("Unknown ASIC type: %d\n", asic); break; } /* turn on USB power */ asic_write(0, usb2_strap); /* Enable all OHCI interrupts */ asic_write(bcm1_usb2_ctl, usb2_control); /* USB2_STBUS_OBC store32/load32 */ asic_write(3, usb2_stbus_obc); /* USB2_STBUS_MESS_SIZE 2 packets */ asic_write(1, usb2_stbus_mess_size); /* USB2_STBUS_CHUNK_SIZE 2 packets */ asic_write(1, usb2_stbus_chunk_size); usb_configured = true; }
int fs_close() //{{{ { fs_file_startblock* file = NULL; if (file_startblock_idx < 0) return FS_ERROR_FILE_NOT_OPEN; // finish updating the file while(fs_busy()) fs_update(); // there is one more partial block that remains to be written uint32_t last_block_idx = file_startblock_idx + BYTES_TO_BLOCKS(file_byte_idx); if (last_block_idx != block_idx) { if (last_block_idx >= fs_capacity) return FS_ERROR_FILE_TOO_LONG; sd_write_block_start(block, last_block_idx); while (sd_write_block_update() < 0); } file = (fs_file_startblock*)block; memset(block, 0, sizeof(block)); file->seq = file_seq; file->byte_len = file_byte_idx; file->fmt_iter = fs_fmt_iter; // write file block if (file_startblock_idx >= fs_capacity) return FS_ERROR_FILE_TOO_LONG; if (!sd_write_block_start(block, file_startblock_idx)) return FS_ERROR_SD_WRITE; while (sd_write_block_update() < 0); // this is a skip file, point to it from the previous skip file if ((file_seq % FS_FILE_SKIP_LEN) == 0 && file_prev_skip_startblock_idx > 0) { // read the prev skip file startblock fs_file_startblock* skip_file = (fs_file_startblock*)block; memset(block, 0, sizeof(block)); if (!sd_read_block(block, file_prev_skip_startblock_idx)) return FS_ERROR_SD_READ; // write prev skip file startblock with the new skip pointer skip_file->next_skip_file_startblock_idx = file_startblock_idx; if (!sd_write_block_start(block, file_prev_skip_startblock_idx)) return FS_ERROR_SD_WRITE; while (sd_write_block_update() < 0); } // reset filesystem state fs_init(); return FS_ERROR_NONE; } //}}}
static void platform_configure_usb(void) { u32 bcm1_usb2_ctl_value; enum asic_type asic_type; unsigned long flags; spin_lock_irqsave(&usb_regs_lock, flags); usb_users++; if (usb_users != 1) { spin_unlock_irqrestore(&usb_regs_lock, flags); return; } asic_type = platform_get_asic(); switch (asic_type) { case ASIC_ZEUS: fs_update(0x0000, -15, 0x02, 0, 0); bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; break; case ASIC_CRONUS: case ASIC_CRONUSLITE: usb_eye_configure(0, CRT_SPARE_USB_DIVIDE_BY_9); fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3, QAM_FS_DISABLE_DIGITAL_STANDBY); bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; break; case ASIC_CALLIOPE: fs_update(0x0000, -15, 0x02, QAM_FS_DISABLE_DIVIDE_BY_3, QAM_FS_DISABLE_DIGITAL_STANDBY); switch (platform_get_family()) { case FAMILY_1500VZE: break; case FAMILY_1500VZF: usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK | CRT_SPARE_PORT1_SHIFT_JK | CRT_SPARE_PORT2_FAST_EDGE | CRT_SPARE_PORT1_FAST_EDGE, 0); break; default: usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK | CRT_SPARE_PORT1_SHIFT_JK, 0); break; } bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK | BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; break; case ASIC_GAIA: fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3, QAM_FS_DISABLE_DIGITAL_STANDBY); bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK | BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH | BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH; break; default: pr_err("Unknown ASIC type: %d\n", asic_type); bcm1_usb2_ctl_value = 0; break; } /* */ asic_write(0, usb2_strap); /* */ asic_write(bcm1_usb2_ctl_value, usb2_control); /* */ asic_write(USB_STBUS_OBC_STORE32_LOAD32, usb2_stbus_obc); /* */ asic_write(USB2_STBUS_MESS_SIZE_2, usb2_stbus_mess_size); /* */ asic_write(USB2_STBUS_CHUNK_SIZE_2, usb2_stbus_chunk_size); spin_unlock_irqrestore(&usb_regs_lock, flags); }
int fs_self_test() //{{{ { uint8_t buf[SD_BLOCK_LEN], buf2[SD_BLOCK_LEN]; uint32_t fmt_iter; int ret, i; printf("fs self test\n"); // start with clean fs and // remember fs_fmt_iter so it can be read after fs_close() format(); fmt_iter = fs_fmt_iter; printf("fs_open new file with no existing file..."); if ((ret = fs_open(1)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } if (file_startblock_idx != 1) { printf("FAILED first new file startblock is not block 1, it's %ld\n", file_startblock_idx); return 1; } printf("PASSED\n"); printf("fs_open existing file with no existing file..."); if ((ret = fs_open(0)) >= 0) { printf("FAILED fs_open did not fail even though it should\n"); return 1; } printf("PASSED\n"); printf("fs_open new file and fs_close..."); if ((ret = fs_open(1)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } if ((ret = fs_close()) < 0) { printf("FAILED fs_close failed, returned %d\n", ret); return 1; } // check file block fs_file_startblock file1; sd_read_block(block, 1); file1.seq = 0; file1.byte_len = 0; file1.fmt_iter = fmt_iter; file1.next_skip_file_startblock_idx = 0; if (memcmp(&file1, block, sizeof(file1)) != 0) { printf("FAILED file block is incorrect\n"); return 1; } printf("PASSED\n"); printf("fs_open another new file and fs_close..."); if ((ret = fs_open(1)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } if ((ret = fs_close()) < 0) { printf("FAILED fs_close failed, returned %d\n", ret); return 1; } // check file block fs_file_startblock file2; sd_read_block(block, 2); file2.fmt_iter = fmt_iter; file2.seq = 1; file2.byte_len = 0; file2.next_skip_file_startblock_idx = 0; if (memcmp(&file2, block, sizeof(file2)) != 0) { printf("FAILED file block is incorrect\n"); return 1; } printf("PASSED\n"); printf("fs_open a new file, write less than a block, and fs_close..."); if ((ret = fs_open(1)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } // write 10 bytes for (i = 0; i < 10; i++) buf[i] = i; fs_write(buf, 10); if ((ret = fs_close()) < 0) { printf("FAILED fs_close failed, returned %d\n", ret); return 1; } // check file block fs_file_startblock file3; sd_read_block(block, 3); file3.fmt_iter = fmt_iter; file3.seq = 2; file3.byte_len = 10; file3.next_skip_file_startblock_idx = 0; if (memcmp(&file3, block, sizeof(file3)) != 0) { printf("FAILED file block is incorrect\n"); return 1; } // check data sd_read_block(block, 4); if (memcmp(buf, block, 10) != 0) { printf("FAILED file data is incorrect\n"); return 1; } printf("PASSED\n"); printf("fs_open a new file, write more than a block, and fs_close..."); if ((ret = fs_open(1)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } memset(buf, (uint8_t)fmt_iter, sizeof(buf)); // write 500 bytes fs_write(buf, 500); while (fs_busy()) fs_update(); memset(buf, (uint8_t)fmt_iter + 1, sizeof(buf)); // write 14 bytes fs_write(buf, 14); if ((ret = fs_close()) < 0) { printf("FAILED fs_close failed, returned %d\n", ret); return 1; } // check file block fs_file_startblock file4; sd_read_block(block, 5); file4.fmt_iter = fmt_iter; file4.seq = 3; file4.byte_len = 514; file4.next_skip_file_startblock_idx = 0; if (memcmp(&file4, block, sizeof(file3)) != 0) { printf("FAILED file block is incorrect\n"); return 1; } // check first block memset(buf, (uint8_t)fmt_iter, sizeof(buf)); sd_read_block(block, 6); if (memcmp(buf, block, 500) != 0) { printf("FAILED file data is incorrect #1\n"); return 1; } memset(buf, (uint8_t)fmt_iter + 1, sizeof(buf)); if (memcmp(buf, block + 500, 12) != 0) { printf("FAILED file data is incorrect #2\n"); return 1; } // check second block sd_read_block(block, 7); if (memcmp(buf, block, 2) != 0) { printf("FAILED file data is incorrect #3\n"); return 1; } printf("PASSED\n"); printf("fs_open an existing file, fs_read more than a block..."); if ((ret = fs_open(0)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } fs_read(buf2, 500); memset(buf, (uint8_t)fmt_iter, sizeof(buf)); if (memcmp(buf, buf2, 500) != 0) { printf("FAILED file data is incorrect #1\n"); return 1; } fs_read(buf2, 14); memset(buf, (uint8_t)fmt_iter + 1, sizeof(buf)); if (memcmp(buf, buf2, 14) != 0) { printf("FAILED file data is incorrect #2\n"); return 1; } if (fs_read(buf2, 1) != FS_ERROR_EOF) { printf("FAILED fs_read should have failed with EOF\n"); return 1; } printf("PASSED\n"); printf("fs_open a new file, big write, big read..."); if ((ret = fs_open(1)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } // init write/read buffer for (i = 0; i < 200; i++) buf[i] = i; // write many times for (i = 0; i < 10; i++) { fs_write(buf, 200); while (fs_busy()) fs_update(); } if ((ret = fs_close()) < 0) { printf("FAILED fs_close failed, returned %d\n", ret); return 1; } if ((ret = fs_open(0)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } // read many times for (i = 0; i < 10; i++) { fs_read(buf2, 200); if (memcmp(buf, buf2, 200) != 0) { printf("FAILED file data is incorrect in iteration %d\n", i); return 1; } } printf("PASSED\n"); // start with clean fs to see if reformat happens correctly // remember fs_fmt_iter so it can be read after fs_close() format(); fmt_iter = fs_fmt_iter; fs_capacity = FS_LAST_FILE_BLOCKS + 2; fs_force_capacity = 1; printf("fs_open file near the end of the disk..."); if ((ret = fs_open(1)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } fs_write(buf, 10); // write one more block if ((ret = fs_close()) < 0) { printf("FAILED fs_close failed, returned %d\n", ret); return 1; } // check file block fs_file_startblock file5; sd_read_block(block, 1); file5.fmt_iter = fmt_iter; file5.seq = 0; file5.byte_len = 10; file5.next_skip_file_startblock_idx = 0; if (memcmp(&file5, block, sizeof(file5)) != 0) { printf("FAILED file block is incorrect\n"); return 1; } printf("PASSED\n"); printf("fs_open file past the end of the last blocks on the disk..."); if ((ret = fs_open(1)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } fs_write(buf, 10); // write one more block if ((ret = fs_close()) < 0) { printf("FAILED fs_close failed, returned %d\n", ret); return 1; } // check file block fs_file_startblock file6; sd_read_block(block, 1); file6.fmt_iter = fmt_iter+1; file6.seq = 0; file6.byte_len = 10; file6.next_skip_file_startblock_idx = 0; if (memcmp(&file6, block, sizeof(file6)) != 0) { printf("FAILED file block is incorrect\n"); return 1; } printf("PASSED\n"); fs_force_capacity = 0; #ifdef FS_SKIP_TEST fs_file_startblock *file = (fs_file_startblock*)block; // start with clean fs so counting skip blocks is possible and // remember fs_fmt_iter so it can be read after fs_close() format(); fmt_iter = fs_fmt_iter; printf("fs_open and fs_close %d files to check skip...", FS_FILE_SKIP_LEN+1); for (i = 0; i < 251; i++) { if ((ret = fs_open(1)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } if ((ret = fs_close()) < 0) { printf("FAILED fs_close failed, returned %d\n", ret); return 1; } } // check file block fs_file_startblock file_skip1; file_skip1.fmt_iter = fmt_iter; file_skip1.seq = 0; file_skip1.byte_len = 0; file_skip1.next_skip_file_startblock_idx = 251; sd_read_block(block, 1); if (memcmp(&file_skip1, block, sizeof(file_skip1)) != 0) { printf("FAILED file skip block is not idx 251, it's %lu\n", file->next_skip_file_startblock_idx); return 1; } printf("PASSED\n"); printf("check if fs_open new uses skip..."); if ((ret = fs_open(1)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } if (fs_open_reads != 3) { printf("FAILED should be 3 iterations to open a file with a skip block, was %ld\n", fs_open_reads); return 1; } if (file_startblock_idx != 252) { printf("FAILED new file is not one after skip block\n"); return 1; } if ((ret = fs_close()) < 0) { printf("FAILED fs_close failed, returned %d\n", ret); return 1; } printf("PASSED\n"); printf("check if fs_open existing uses skip..."); if ((ret = fs_open(0)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } if (fs_open_reads != 4) { printf("FAILED should be 4 iterations to open a file with a skip block, was %ld\n", fs_open_reads); return 1; } if (file_startblock_idx != 252) { printf("FAILED new file is not one after skip block\n"); return 1; } if ((ret = fs_close()) < 0) { printf("FAILED fs_close failed, returned %d\n", ret); return 1; } printf("PASSED\n"); printf("fs_open, fs_write, fs_close %d files to check 2nd skip...", FS_FILE_SKIP_LEN+1); for (i = 0; i < 251; i++) { if ((ret = fs_open(1)) < 0) { printf("FAILED fs_open failed, returned %d\n", ret); return 1; } fs_write(buf, 200); if ((ret = fs_close()) < 0) { printf("FAILED fs_close failed, returned %d\n", ret); return 1; } } // check file block fs_file_startblock file_skip2; file_skip2.fmt_iter = fmt_iter; file_skip2.seq = 250; file_skip2.byte_len = 0; file_skip2.next_skip_file_startblock_idx = 750; sd_read_block(block, 251); if (memcmp(&file_skip2, block, sizeof(file_skip2)) != 0) { printf("FAILED file skip block is not idx 750, it's %lu\n", file->next_skip_file_startblock_idx); return 1; } printf("PASSED\n"); #endif return 0; } //}}}