diff options
Diffstat (limited to 'drivers')
62 files changed, 527 insertions, 376 deletions
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 6512b20aeccd..d1fcbc0f6cbc 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -292,7 +292,9 @@ static int acpi_ac_add(struct acpi_device *device) ac->charger.properties = ac_props; ac->charger.num_properties = ARRAY_SIZE(ac_props); ac->charger.get_property = get_ac_property; - power_supply_register(&ac->device->dev, &ac->charger); + result = power_supply_register(&ac->device->dev, &ac->charger); + if (result) + goto end; printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 6686b1eaf13e..00a783661d0b 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -586,6 +586,11 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr, } *access_bit_width = 1UL << (access_size_code + 2); + /* Fixup common BIOS bug */ + if (bit_width == 32 && bit_offset == 0 && (*paddr & 0x03) == 0 && + *access_bit_width < 32) + *access_bit_width = 32; + if ((bit_width + bit_offset) > *access_bit_width) { pr_warning(FW_BUG APEI_PFX "Invalid bit width + offset in GAR [0x%llx/%u/%u/%u/%u]\n", diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index ad7c7320dd1b..08427abf5fa5 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -827,10 +827,10 @@ EXPORT_SYMBOL_GPL(tpm_pcr_extend); int tpm_do_selftest(struct tpm_chip *chip) { int rc; - u8 digest[TPM_DIGEST_SIZE]; unsigned int loops; unsigned int delay_msec = 1000; unsigned long duration; + struct tpm_cmd_t cmd; duration = tpm_calc_ordinal_duration(chip, TPM_ORD_CONTINUE_SELFTEST); @@ -845,7 +845,15 @@ int tpm_do_selftest(struct tpm_chip *chip) return rc; do { - rc = __tpm_pcr_read(chip, 0, digest); + /* Attempt to read a PCR value */ + cmd.header.in = pcrread_header; + cmd.params.pcrread_in.pcr_idx = cpu_to_be32(0); + rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE); + + if (rc < TPM_HEADER_SIZE) + return -EFAULT; + + rc = be32_to_cpu(cmd.header.out.return_code); if (rc == TPM_ERR_DISABLED || rc == TPM_ERR_DEACTIVATED) { dev_info(chip->dev, "TPM is disabled/deactivated (0x%X)\n", rc); diff --git a/drivers/gpu/drm/nouveau/nva3_copy.fuc b/drivers/gpu/drm/nouveau/nva3_copy.fuc index abc36626fef0..219850d53286 100644 --- a/drivers/gpu/drm/nouveau/nva3_copy.fuc +++ b/drivers/gpu/drm/nouveau/nva3_copy.fuc @@ -119,9 +119,9 @@ dispatch_dma: // mthd 0x030c-0x0340, various stuff .b16 0xc3 14 .b32 #ctx_src_address_high ~0x000000ff -.b32 #ctx_src_address_low ~0xfffffff0 +.b32 #ctx_src_address_low ~0xffffffff .b32 #ctx_dst_address_high ~0x000000ff -.b32 #ctx_dst_address_low ~0xfffffff0 +.b32 #ctx_dst_address_low ~0xffffffff .b32 #ctx_src_pitch ~0x0007ffff .b32 #ctx_dst_pitch ~0x0007ffff .b32 #ctx_xcnt ~0x0000ffff diff --git a/drivers/gpu/drm/nouveau/nva3_copy.fuc.h b/drivers/gpu/drm/nouveau/nva3_copy.fuc.h index 1f33fbdc00be..37d6de3c9d61 100644 --- a/drivers/gpu/drm/nouveau/nva3_copy.fuc.h +++ b/drivers/gpu/drm/nouveau/nva3_copy.fuc.h @@ -1,37 +1,72 @@ -uint32_t nva3_pcopy_data[] = { +u32 nva3_pcopy_data[] = { +/* 0x0000: ctx_object */ 0x00000000, +/* 0x0004: ctx_dma */ +/* 0x0004: ctx_dma_query */ 0x00000000, +/* 0x0008: ctx_dma_src */ 0x00000000, +/* 0x000c: ctx_dma_dst */ 0x00000000, +/* 0x0010: ctx_query_address_high */ 0x00000000, +/* 0x0014: ctx_query_address_low */ 0x00000000, +/* 0x0018: ctx_query_counter */ 0x00000000, +/* 0x001c: ctx_src_address_high */ 0x00000000, +/* 0x0020: ctx_src_address_low */ 0x00000000, +/* 0x0024: ctx_src_pitch */ 0x00000000, +/* 0x0028: ctx_src_tile_mode */ 0x00000000, +/* 0x002c: ctx_src_xsize */ 0x00000000, +/* 0x0030: ctx_src_ysize */ 0x00000000, +/* 0x0034: ctx_src_zsize */ 0x00000000, +/* 0x0038: ctx_src_zoff */ 0x00000000, +/* 0x003c: ctx_src_xoff */ 0x00000000, +/* 0x0040: ctx_src_yoff */ 0x00000000, +/* 0x0044: ctx_src_cpp */ 0x00000000, +/* 0x0048: ctx_dst_address_high */ 0x00000000, +/* 0x004c: ctx_dst_address_low */ 0x00000000, +/* 0x0050: ctx_dst_pitch */ 0x00000000, +/* 0x0054: ctx_dst_tile_mode */ 0x00000000, +/* 0x0058: ctx_dst_xsize */ 0x00000000, +/* 0x005c: ctx_dst_ysize */ 0x00000000, +/* 0x0060: ctx_dst_zsize */ 0x00000000, +/* 0x0064: ctx_dst_zoff */ 0x00000000, +/* 0x0068: ctx_dst_xoff */ 0x00000000, +/* 0x006c: ctx_dst_yoff */ 0x00000000, +/* 0x0070: ctx_dst_cpp */ 0x00000000, +/* 0x0074: ctx_format */ 0x00000000, +/* 0x0078: ctx_swz_const0 */ 0x00000000, +/* 0x007c: ctx_swz_const1 */ 0x00000000, +/* 0x0080: ctx_xcnt */ 0x00000000, +/* 0x0084: ctx_ycnt */ 0x00000000, 0x00000000, 0x00000000, @@ -63,6 +98,7 @@ uint32_t nva3_pcopy_data[] = { 0x00000000, 0x00000000, 0x00000000, +/* 0x0100: dispatch_table */ 0x00010000, 0x00000000, 0x00000000, @@ -73,6 +109,7 @@ uint32_t nva3_pcopy_data[] = { 0x00010162, 0x00000000, 0x00030060, +/* 0x0128: dispatch_dma */ 0x00010170, 0x00000000, 0x00010170, @@ -118,11 +155,11 @@ uint32_t nva3_pcopy_data[] = { 0x0000001c, 0xffffff00, 0x00000020, - 0x0000000f, + 0x00000000, 0x00000048, 0xffffff00, 0x0000004c, - 0x0000000f, + 0x00000000, 0x00000024, 0xfff80000, 0x00000050, @@ -146,7 +183,8 @@ uint32_t nva3_pcopy_data[] = { 0x00000800, }; -uint32_t nva3_pcopy_code[] = { +u32 nva3_pcopy_code[] = { +/* 0x0000: main */ 0x04fe04bd, 0x3517f000, 0xf10010fe, @@ -158,23 +196,31 @@ uint32_t nva3_pcopy_code[] = { 0x17f11031, 0x27f01200, 0x0012d003, +/* 0x002f: spin */ 0xf40031f4, 0x0ef40028, +/* 0x0035: ih */ 0x8001cffd, 0xf40812c4, 0x21f4060b, +/* 0x0041: ih_no_chsw */ 0x0412c472, 0xf4060bf4, +/* 0x004a: ih_no_cmd */ 0x11c4c321, 0x4001d00c, +/* 0x0052: swctx */ 0x47f101f8, 0x4bfe7700, 0x0007fe00, 0xf00204b9, 0x01f40643, 0x0604fa09, +/* 0x006b: swctx_load */ 0xfa060ef4, +/* 0x006e: swctx_done */ 0x03f80504, +/* 0x0072: chsw */ 0x27f100f8, 0x23cf1400, 0x1e3fc800, @@ -183,18 +229,22 @@ uint32_t nva3_pcopy_code[] = { 0x1e3af052, 0xf00023d0, 0x24d00147, +/* 0x0093: chsw_no_unload */ 0xcf00f880, 0x3dc84023, 0x220bf41e, 0xf40131f4, 0x57f05221, 0x0367f004, +/* 0x00a8: chsw_load_ctx_dma */ 0xa07856bc, 0xb6018068, 0x87d00884, 0x0162b600, +/* 0x00bb: chsw_finish_load */ 0xf0f018f4, 0x23d00237, +/* 0x00c3: dispatch */ 0xf100f880, 0xcf190037, 0x33cf4032, @@ -202,6 +252,7 @@ uint32_t nva3_pcopy_code[] = { 0x1024b607, 0x010057f1, 0x74bd64bd, +/* 0x00dc: dispatch_loop */ 0x58005658, 0x50b60157, 0x0446b804, @@ -211,6 +262,7 @@ uint32_t nva3_pcopy_code[] = { 0xb60276bb, 0x57bb0374, 0xdf0ef400, +/* 0x0100: dispatch_valid_mthd */ 0xb60246bb, 0x45bb0344, 0x01459800, @@ -220,31 +272,41 @@ uint32_t nva3_pcopy_code[] = { 0xb0014658, 0x1bf40064, 0x00538009, +/* 0x0127: dispatch_cmd */ 0xf4300ef4, 0x55f90132, 0xf40c01f4, +/* 0x0132: dispatch_invalid_bitfield */ 0x25f0250e, +/* 0x0135: dispatch_illegal_mthd */ 0x0125f002, +/* 0x0138: dispatch_error */ 0x100047f1, 0xd00042d0, 0x27f04043, 0x0002d040, +/* 0x0148: hostirq_wait */ 0xf08002cf, 0x24b04024, 0xf71bf400, +/* 0x0154: dispatch_done */ 0x1d0027f1, 0xd00137f0, 0x00f80023, +/* 0x0160: cmd_nop */ +/* 0x0162: cmd_pm_trigger */ 0x27f100f8, 0x34bd2200, 0xd00233f0, 0x00f80023, +/* 0x0170: cmd_dma */ 0x012842b7, 0xf00145b6, 0x43801e39, 0x0040b701, 0x0644b606, 0xf80043d0, +/* 0x0189: cmd_exec_set_format */ 0xf030f400, 0xb00001b0, 0x01b00101, @@ -256,20 +318,26 @@ uint32_t nva3_pcopy_code[] = { 0x70b63847, 0x0232f401, 0x94bd84bd, +/* 0x01b4: ncomp_loop */ 0xb60f4ac4, 0xb4bd0445, +/* 0x01bc: bpc_loop */ 0xf404a430, 0xa5ff0f18, 0x00cbbbc0, 0xf40231f4, +/* 0x01ce: cmp_c0 */ 0x1bf4220e, 0x10c7f00c, 0xf400cbbb, +/* 0x01da: cmp_c1 */ 0xa430160e, 0x0c18f406, 0xbb14c7f0, 0x0ef400cb, +/* 0x01e9: cmp_zero */ 0x80c7f107, +/* 0x01ed: bpc_next */ 0x01c83800, 0xb60180b6, 0xb5b801b0, @@ -280,6 +348,7 @@ uint32_t nva3_pcopy_code[] = { 0x98110680, 0x68fd2008, 0x0502f400, +/* 0x0216: dst_xcnt */ 0x75fd64bd, 0x1c078000, 0xf10078fd, @@ -304,6 +373,7 @@ uint32_t nva3_pcopy_code[] = { 0x980056d0, 0x56d01f06, 0x1030f440, +/* 0x0276: cmd_exec_set_surface_tiled */ 0x579800f8, 0x6879c70a, 0xb66478c7, @@ -311,9 +381,11 @@ uint32_t nva3_pcopy_code[] = { 0x0e76b060, 0xf0091bf4, 0x0ef40477, +/* 0x0291: xtile64 */ 0x027cf00f, 0xfd1170b6, 0x77f00947, +/* 0x029d: xtileok */ 0x0f5a9806, 0xfd115b98, 0xb7f000ab, @@ -371,6 +443,7 @@ uint32_t nva3_pcopy_code[] = { 0x67d00600, 0x0060b700, 0x0068d004, +/* 0x0382: cmd_exec_set_surface_linear */ 0x6cf000f8, 0x0260b702, 0x0864b602, @@ -381,13 +454,16 @@ uint32_t nva3_pcopy_code[] = { 0xb70067d0, 0x98040060, 0x67d00957, +/* 0x03ab: cmd_exec_wait */ 0xf900f800, 0xf110f900, 0xb6080007, +/* 0x03b6: loop */ 0x01cf0604, 0x0114f000, 0xfcfa1bf4, 0xf800fc10, +/* 0x03c5: cmd_exec_query */ 0x0d34c800, 0xf5701bf4, 0xf103ab21, @@ -417,6 +493,7 @@ uint32_t nva3_pcopy_code[] = { 0x47f10153, 0x44b60800, 0x0045d006, +/* 0x0438: query_counter */ 0x03ab21f5, 0x080c47f1, 0x980644b6, @@ -439,11 +516,13 @@ uint32_t nva3_pcopy_code[] = { 0x47f10153, 0x44b60800, 0x0045d006, +/* 0x0492: cmd_exec */ 0x21f500f8, 0x3fc803ab, 0x0e0bf400, 0x018921f5, 0x020047f1, +/* 0x04a7: cmd_exec_no_format */ 0xf11e0ef4, 0xb6081067, 0x77f00664, @@ -451,19 +530,24 @@ uint32_t nva3_pcopy_code[] = { 0x981c0780, 0x67d02007, 0x4067d000, +/* 0x04c2: cmd_exec_init_src_surface */ 0x32f444bd, 0xc854bd02, 0x0bf4043f, 0x8221f50a, 0x0a0ef403, +/* 0x04d4: src_tiled */ 0x027621f5, +/* 0x04db: cmd_exec_init_dst_surface */ 0xf40749f0, 0x57f00231, 0x083fc82c, 0xf50a0bf4, 0xf4038221, +/* 0x04ee: dst_tiled */ 0x21f50a0e, 0x49f00276, +/* 0x04f5: cmd_exec_kick */ 0x0057f108, 0x0654b608, 0xd0210698, @@ -473,6 +557,8 @@ uint32_t nva3_pcopy_code[] = { 0xc80054d0, 0x0bf40c3f, 0xc521f507, +/* 0x0519: cmd_exec_done */ +/* 0x051b: cmd_wrcache_flush */ 0xf100f803, 0xbd220027, 0x0133f034, diff --git a/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h b/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h index a8d17458ced1..cd879f31bb38 100644 --- a/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h +++ b/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h @@ -1,34 +1,65 @@ -uint32_t nvc0_pcopy_data[] = { +u32 nvc0_pcopy_data[] = { +/* 0x0000: ctx_object */ 0x00000000, +/* 0x0004: ctx_query_address_high */ 0x00000000, +/* 0x0008: ctx_query_address_low */ 0x00000000, +/* 0x000c: ctx_query_counter */ 0x00000000, +/* 0x0010: ctx_src_address_high */ 0x00000000, +/* 0x0014: ctx_src_address_low */ 0x00000000, +/* 0x0018: ctx_src_pitch */ 0x00000000, +/* 0x001c: ctx_src_tile_mode */ 0x00000000, +/* 0x0020: ctx_src_xsize */ 0x00000000, +/* 0x0024: ctx_src_ysize */ 0x00000000, +/* 0x0028: ctx_src_zsize */ 0x00000000, +/* 0x002c: ctx_src_zoff */ 0x00000000, +/* 0x0030: ctx_src_xoff */ 0x00000000, +/* 0x0034: ctx_src_yoff */ 0x00000000, +/* 0x0038: ctx_src_cpp */ 0x00000000, +/* 0x003c: ctx_dst_address_high */ 0x00000000, +/* 0x0040: ctx_dst_address_low */ 0x00000000, +/* 0x0044: ctx_dst_pitch */ 0x00000000, +/* 0x0048: ctx_dst_tile_mode */ 0x00000000, +/* 0x004c: ctx_dst_xsize */ 0x00000000, +/* 0x0050: ctx_dst_ysize */ 0x00000000, +/* 0x0054: ctx_dst_zsize */ 0x00000000, +/* 0x0058: ctx_dst_zoff */ 0x00000000, +/* 0x005c: ctx_dst_xoff */ 0x00000000, +/* 0x0060: ctx_dst_yoff */ 0x00000000, +/* 0x0064: ctx_dst_cpp */ 0x00000000, +/* 0x0068: ctx_format */ 0x00000000, +/* 0x006c: ctx_swz_const0 */ 0x00000000, +/* 0x0070: ctx_swz_const1 */ 0x00000000, +/* 0x0074: ctx_xcnt */ 0x00000000, +/* 0x0078: ctx_ycnt */ 0x00000000, 0x00000000, 0x00000000, @@ -63,6 +94,7 @@ uint32_t nvc0_pcopy_data[] = { 0x00000000, 0x00000000, 0x00000000, +/* 0x0100: dispatch_table */ 0x00010000, 0x00000000, 0x00000000, @@ -111,11 +143,11 @@ uint32_t nvc0_pcopy_data[] = { 0x00000010, 0xffffff00, 0x00000014, - 0x0000000f, + 0x00000000, 0x0000003c, 0xffffff00, 0x00000040, - 0x0000000f, + 0x00000000, 0x00000018, 0xfff80000, 0x00000044, @@ -139,7 +171,8 @@ uint32_t nvc0_pcopy_data[] = { 0x00000800, }; -uint32_t nvc0_pcopy_code[] = { +u32 nvc0_pcopy_code[] = { +/* 0x0000: main */ 0x04fe04bd, 0x3517f000, 0xf10010fe, @@ -151,15 +184,20 @@ uint32_t nvc0_pcopy_code[] = { 0x17f11031, 0x27f01200, 0x0012d003, +/* 0x002f: spin */ 0xf40031f4, 0x0ef40028, +/* 0x0035: ih */ 0x8001cffd, 0xf40812c4, 0x21f4060b, +/* 0x0041: ih_no_chsw */ 0x0412c4ca, 0xf5070bf4, +/* 0x004b: ih_no_cmd */ 0xc4010221, 0x01d00c11, +/* 0x0053: swctx */ 0xf101f840, 0xfe770047, 0x47f1004b, @@ -188,8 +226,11 @@ uint32_t nvc0_pcopy_code[] = { 0xf00204b9, 0x01f40643, 0x0604fa09, +/* 0x00c3: swctx_load */ 0xfa060ef4, +/* 0x00c6: swctx_done */ 0x03f80504, +/* 0x00ca: chsw */ 0x27f100f8, 0x23cf1400, 0x1e3fc800, @@ -198,18 +239,22 @@ uint32_t nvc0_pcopy_code[] = { 0x1e3af053, 0xf00023d0, 0x24d00147, +/* 0x00eb: chsw_no_unload */ 0xcf00f880, 0x3dc84023, 0x090bf41e, 0xf40131f4, +/* 0x00fa: chsw_finish_load */ 0x37f05321, 0x8023d002, +/* 0x0102: dispatch */ 0x37f100f8, 0x32cf1900, 0x0033cf40, 0x07ff24e4, 0xf11024b6, 0xbd010057, +/* 0x011b: dispatch_loop */ 0x5874bd64, 0x57580056, 0x0450b601, @@ -219,6 +264,7 @@ uint32_t nvc0_pcopy_code[] = { 0xbb0f08f4, 0x74b60276, 0x0057bb03, +/* 0x013f: dispatch_valid_mthd */ 0xbbdf0ef4, 0x44b60246, 0x0045bb03, @@ -229,24 +275,33 @@ uint32_t nvc0_pcopy_code[] = { 0x64b00146, 0x091bf400, 0xf4005380, +/* 0x0166: dispatch_cmd */ 0x32f4300e, 0xf455f901, 0x0ef40c01, +/* 0x0171: dispatch_invalid_bitfield */ 0x0225f025, +/* 0x0174: dispatch_illegal_mthd */ +/* 0x0177: dispatch_error */ 0xf10125f0, 0xd0100047, 0x43d00042, 0x4027f040, +/* 0x0187: hostirq_wait */ 0xcf0002d0, 0x24f08002, 0x0024b040, +/* 0x0193: dispatch_done */ 0xf1f71bf4, 0xf01d0027, 0x23d00137, +/* 0x019f: cmd_nop */ 0xf800f800, +/* 0x01a1: cmd_pm_trigger */ 0x0027f100, 0xf034bd22, 0x23d00233, +/* 0x01af: cmd_exec_set_format */ 0xf400f800, 0x01b0f030, 0x0101b000, @@ -258,20 +313,26 @@ uint32_t nvc0_pcopy_code[] = { 0x3847c701, 0xf40170b6, 0x84bd0232, +/* 0x01da: ncomp_loop */ 0x4ac494bd, 0x0445b60f, +/* 0x01e2: bpc_loop */ 0xa430b4bd, 0x0f18f404, 0xbbc0a5ff, 0x31f400cb, 0x220ef402, +/* 0x01f4: cmp_c0 */ 0xf00c1bf4, 0xcbbb10c7, 0x160ef400, +/* 0x0200: cmp_c1 */ 0xf406a430, 0xc7f00c18, 0x00cbbb14, +/* 0x020f: cmp_zero */ 0xf1070ef4, +/* 0x0213: bpc_next */ 0x380080c7, 0x80b601c8, 0x01b0b601, @@ -283,6 +344,7 @@ uint32_t nvc0_pcopy_code[] = { 0x1d08980e, 0xf40068fd, 0x64bd0502, +/* 0x023c: dst_xcnt */ 0x800075fd, 0x78fd1907, 0x1057f100, @@ -307,15 +369,18 @@ uint32_t nvc0_pcopy_code[] = { 0x1c069800, 0xf44056d0, 0x00f81030, +/* 0x029c: cmd_exec_set_surface_tiled */ 0xc7075798, 0x78c76879, 0x0380b664, 0xb06077c7, 0x1bf40e76, 0x0477f009, +/* 0x02b7: xtile64 */ 0xf00f0ef4, 0x70b6027c, 0x0947fd11, +/* 0x02c3: xtileok */ 0x980677f0, 0x5b980c5a, 0x00abfd0e, @@ -374,6 +439,7 @@ uint32_t nvc0_pcopy_code[] = { 0xb70067d0, 0xd0040060, 0x00f80068, +/* 0x03a8: cmd_exec_set_surface_linear */ 0xb7026cf0, 0xb6020260, 0x57980864, @@ -384,12 +450,15 @@ uint32_t nvc0_pcopy_code[] = { 0x0060b700, 0x06579804, 0xf80067d0, +/* 0x03d1: cmd_exec_wait */ 0xf900f900, 0x0007f110, 0x0604b608, +/* 0x03dc: loop */ 0xf00001cf, 0x1bf40114, 0xfc10fcfa, +/* 0x03eb: cmd_exec_query */ 0xc800f800, 0x1bf40d34, 0xd121f570, @@ -419,6 +488,7 @@ uint32_t nvc0_pcopy_code[] = { 0x0153f026, 0x080047f1, 0xd00644b6, +/* 0x045e: query_counter */ 0x21f50045, 0x47f103d1, 0x44b6080c, @@ -442,11 +512,13 @@ uint32_t nvc0_pcopy_code[] = { 0x080047f1, 0xd00644b6, 0x00f80045, +/* 0x04b8: cmd_exec */ 0x03d121f5, 0xf4003fc8, 0x21f50e0b, 0x47f101af, 0x0ef40200, +/* 0x04cd: cmd_exec_no_format */ 0x1067f11e, 0x0664b608, 0x800177f0, @@ -454,18 +526,23 @@ uint32_t nvc0_pcopy_code[] = { 0x1d079819, 0xd00067d0, 0x44bd4067, +/* 0x04e8: cmd_exec_init_src_surface */ 0xbd0232f4, 0x043fc854, 0xf50a0bf4, 0xf403a821, +/* 0x04fa: src_tiled */ 0x21f50a0e, 0x49f0029c, +/* 0x0501: cmd_exec_init_dst_surface */ 0x0231f407, 0xc82c57f0, 0x0bf4083f, 0xa821f50a, 0x0a0ef403, +/* 0x0514: dst_tiled */ 0x029c21f5, +/* 0x051b: cmd_exec_kick */ 0xf10849f0, 0xb6080057, 0x06980654, @@ -475,7 +552,9 @@ uint32_t nvc0_pcopy_code[] = { 0x54d00546, 0x0c3fc800, 0xf5070bf4, +/* 0x053f: cmd_exec_done */ 0xf803eb21, +/* 0x0541: cmd_wrcache_flush */ 0x0027f100, 0xf034bd22, 0x23d00133, diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index c57d85664e77..886b41f44a55 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -22,6 +22,7 @@ * * Authors: Dave Airlie * Alex Deucher + * Jerome Glisse */ #include "drmP.h" #include "radeon_drm.h" @@ -637,7 +638,6 @@ static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector, ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, link_status, DP_LINK_STATUS_SIZE, 100); if (ret <= 0) { - DRM_ERROR("displayport link status failed\n"); return false; } @@ -816,8 +816,10 @@ static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info) else mdelay(dp_info->rd_interval * 4); - if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) + if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { + DRM_ERROR("displayport link status failed\n"); break; + } if (dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) { clock_recovery = true; @@ -879,8 +881,10 @@ static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info) else mdelay(dp_info->rd_interval * 4); - if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) + if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { + DRM_ERROR("displayport link status failed\n"); break; + } if (dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) { channel_eq = true; diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 2d39f9977e00..a3ae788a2af2 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1392,10 +1392,18 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) case DRM_MODE_DPMS_ON: /* some early dce3.2 boards have a bug in their transmitter control table */ if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || - ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) + ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { + if (ASIC_IS_DCE6(rdev)) { + /* It seems we need to call ATOM_ENCODER_CMD_SETUP again + * before reenabling encoder on DPMS ON, otherwise we never + * get picture + */ + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); + } atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); - else + } else { atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); + } if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { atombios_set_edp_panel_power(connector, diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 3c2e7a000a2a..3fb7ca922069 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -64,14 +64,33 @@ void radeon_connector_hotplug(struct drm_connector *connector) /* just deal with DP (not eDP) here. */ if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { - int saved_dpms = connector->dpms; - - /* Only turn off the display it it's physically disconnected */ - if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - else if (radeon_dp_needs_link_train(radeon_connector)) - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - connector->dpms = saved_dpms; + struct radeon_connector_atom_dig *dig_connector = + radeon_connector->con_priv; + + /* if existing sink type was not DP no need to retrain */ + if (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT) + return; + + /* first get sink type as it may be reset after (un)plug */ + dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); + /* don't do anything if sink is not display port, i.e., + * passive dp->(dvi|hdmi) adaptor + */ + if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { + int saved_dpms = connector->dpms; + /* Only turn off the display if it's physically disconnected */ + if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); + } else if (radeon_dp_needs_link_train(radeon_connector)) { + /* set it to OFF so that drm_helper_connector_dpms() + * won't return immediately since the current state + * is ON at this point. + */ + connector->dpms = DRM_MODE_DPMS_OFF; + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); + } + connector->dpms = saved_dpms; + } } } diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 2418cf6da1c1..cf723c4297a9 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -377,7 +377,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, if (r) { DRM_ERROR("Failed to schedule IB !\n"); } - return 0; + return r; } static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 42acc6449dd6..711e95ad39bf 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -262,8 +262,14 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, if (!(cursor_end & 0x7f)) w--; } - if (w <= 0) + if (w <= 0) { w = 1; + cursor_end = x - xorigin + w; + if (!(cursor_end & 0x7f)) { + x--; + WARN_ON_ONCE(x < 0); + } + } } } diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index df6a4dbd93f8..80c6e8bad656 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -136,7 +136,6 @@ int radeon_bo_create(struct radeon_device *rdev, acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, sizeof(struct radeon_bo)); -retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); if (bo == NULL) return -ENOMEM; @@ -150,6 +149,8 @@ retry: bo->surface_reg = -1; INIT_LIST_HEAD(&bo->list); INIT_LIST_HEAD(&bo->va); + +retry: radeon_ttm_placement_from_domain(bo, domain); /* Kernel allocation are uninterruptible */ mutex_lock(&rdev->vram_mutex); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 054677b3d168..973c238eb9f6 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1391,6 +1391,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, + { HID_USB_DEVICE(USB_VENDOR_ID_BAANTO, USB_DEVICE_ID_BAANTO_MT_190W2), }, { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index dfd40981c86a..bb1abf83798b 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -160,6 +160,9 @@ #define USB_VENDOR_ID_AVERMEDIA 0x07ca #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 +#define USB_VENDOR_ID_BAANTO 0x2453 +#define USB_DEVICE_ID_BAANTO_MT_190W2 0x0100 + #define USB_VENDOR_ID_BELKIN 0x050d #define USB_DEVICE_ID_FLIP_KVM 0x3201 @@ -650,6 +653,9 @@ #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 +#define USB_VENDOR_ID_SENNHEISER 0x1395 +#define USB_DEVICE_ID_SENNHEISER_BTD500USB 0x002c + #define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f #define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002 diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index c19bff70ce7b..43669731afc9 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -290,6 +290,9 @@ static const struct hid_device_id hid_battery_quirks[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, + USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), + HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, {} }; diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 8cf4310af9fc..fad168476a14 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -793,6 +793,10 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) }, + /* Baanto multitouch devices */ + { .driver_data = MT_CLS_DEFAULT, + HID_USB_DEVICE(USB_VENDOR_ID_BAANTO, + USB_DEVICE_ID_BAANTO_MT_190W2) }, /* Cando panels */ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, HID_USB_DEVICE(USB_VENDOR_ID_CANDO, diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 782c63955f29..82f61ee632b5 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -76,6 +76,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index dfe7d37c82c5..57ed244cf990 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -2254,6 +2254,18 @@ static int device_change_notifier(struct notifier_block *nb, iommu_init_device(dev); + /* + * dev_data is still NULL and + * got initialized in iommu_init_device + */ + dev_data = get_dev_data(dev); + + if (iommu_pass_through || dev_data->iommu_v2) { + dev_data->passthrough = true; + attach_device(dev, pt_domain); + break; + } + domain = domain_for_device(dev); /* allocate a protection domain if a device is added */ @@ -2271,10 +2283,7 @@ static int device_change_notifier(struct notifier_block *nb, dev_data = get_dev_data(dev); - if (!dev_data->passthrough) - dev->archdata.dma_ops = &amd_iommu_dma_ops; - else - dev->archdata.dma_ops = &nommu_dma_ops; + dev->archdata.dma_ops = &amd_iommu_dma_ops; break; case BUS_NOTIFY_DEL_DEVICE: diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index 036fe9bf157e..a1f1bc876043 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c @@ -681,6 +681,8 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid, atomic_set(&pasid_state->count, 1); init_waitqueue_head(&pasid_state->wq); + spin_lock_init(&pasid_state->lock); + pasid_state->task = task; pasid_state->mm = get_task_mm(task); pasid_state->device_state = dev_state; diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index d039de8322f0..b58b7a33914a 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -1084,6 +1084,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->split_io = dm_rh_get_region_size(ms->rh); ti->num_flush_requests = 1; ti->num_discard_requests = 1; + ti->discard_zeroes_data_unsupported = 1; ms->kmirrord_wq = alloc_workqueue("kmirrord", WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); @@ -1214,7 +1215,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, * We need to dec pending if this was a write. */ if (rw == WRITE) { - if (!(bio->bi_rw & REQ_FLUSH)) + if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) dm_rh_dec(ms->rh, map_context->ll); return error; } diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index 7771ed212182..69732e03eb34 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c @@ -404,6 +404,9 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio) return; } + if (bio->bi_rw & REQ_DISCARD) + return; + /* We must inform the log that the sync count has changed. */ log->type->set_region_sync(log, region, 0); @@ -524,7 +527,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios) struct bio *bio; for (bio = bios->head; bio; bio = bio->bi_next) { - if (bio->bi_rw & REQ_FLUSH) + if (bio->bi_rw & (REQ_FLUSH | REQ_DISCARD)) continue; rh_inc(rh, dm_rh_bio_to_region(rh, bio)); } diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index eb3d138ff55a..1555f0b2a2be 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -19,7 +19,7 @@ /* * Tunable constants */ -#define ENDIO_HOOK_POOL_SIZE 10240 +#define ENDIO_HOOK_POOL_SIZE 1024 #define DEFERRED_SET_SIZE 64 #define MAPPING_POOL_SIZE 1024 #define PRISON_CELLS 1024 @@ -855,7 +855,7 @@ static void process_prepared_mapping(struct new_mapping *m) if (m->err) { cell_error(m->cell); - return; + goto out; } /* @@ -867,7 +867,7 @@ static void process_prepared_mapping(struct new_mapping *m) if (r) { DMERR("dm_thin_insert_block() failed"); cell_error(m->cell); - return; + goto out; } /* @@ -882,6 +882,7 @@ static void process_prepared_mapping(struct new_mapping *m) } else cell_defer(tc, m->cell, m->data_block); +out: list_del(&m->list); mempool_free(m, tc->pool->mapping_pool); } @@ -1240,7 +1241,10 @@ static void process_discard(struct thin_c *tc, struct bio *bio) cell_release_singleton(cell, bio); cell_release_singleton(cell2, bio); - remap_and_issue(tc, bio, lookup_result.block); + if ((!lookup_result.shared) && pool->pf.discard_passdown) + remap_and_issue(tc, bio, lookup_result.block); + else + bio_endio(bio, 0); } break; @@ -2575,6 +2579,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) if (tc->pool->pf.discard_enabled) { ti->discards_supported = 1; ti->num_discard_requests = 1; + ti->discard_zeroes_data_unsupported = 1; } dm_put(pool_md); diff --git a/drivers/md/md.c b/drivers/md/md.c index 2b30ffdb81b2..9ee8ce3e9650 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3744,8 +3744,8 @@ array_state_show(struct mddev *mddev, char *page) return sprintf(page, "%s\n", array_states[st]); } -static int do_md_stop(struct mddev * mddev, int ro, int is_open); -static int md_set_readonly(struct mddev * mddev, int is_open); +static int do_md_stop(struct mddev * mddev, int ro, struct block_device *bdev); +static int md_set_readonly(struct mddev * mddev, struct block_device *bdev); static int do_md_run(struct mddev * mddev); static int restart_array(struct mddev *mddev); @@ -3761,14 +3761,14 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) /* stopping an active array */ if (atomic_read(&mddev->openers) > 0) return -EBUSY; - err = do_md_stop(mddev, 0, 0); + err = do_md_stop(mddev, 0, NULL); break; case inactive: /* stopping an active array */ if (mddev->pers) { if (atomic_read(&mddev->openers) > 0) return -EBUSY; - err = do_md_stop(mddev, 2, 0); + err = do_md_stop(mddev, 2, NULL); } else err = 0; /* already inactive */ break; @@ -3776,7 +3776,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) break; /* not supported yet */ case readonly: if (mddev->pers) - err = md_set_readonly(mddev, 0); + err = md_set_readonly(mddev, NULL); else { mddev->ro = 1; set_disk_ro(mddev->gendisk, 1); @@ -3786,7 +3786,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) case read_auto: if (mddev->pers) { if (mddev->ro == 0) - err = md_set_readonly(mddev, 0); + err = md_set_readonly(mddev, NULL); else if (mddev->ro == 1) err = restart_array(mddev); if (err == 0) { @@ -5124,15 +5124,17 @@ void md_stop(struct mddev *mddev) } EXPORT_SYMBOL_GPL(md_stop); -static int md_set_readonly(struct mddev *mddev, int is_open) +static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) { int err = 0; mutex_lock(&mddev->open_mutex); - if (atomic_read(&mddev->openers) > is_open) { + if (atomic_read(&mddev->openers) > !!bdev) { printk("md: %s still in use.\n",mdname(mddev)); err = -EBUSY; goto out; } + if (bdev) + sync_blockdev(bdev); if (mddev->pers) { __md_stop_writes(mddev); @@ -5154,18 +5156,26 @@ out: * 0 - completely stop and dis-assemble array * 2 - stop but do not disassemble array */ -static int do_md_stop(struct mddev * mddev, int mode, int is_open) +static int do_md_stop(struct mddev * mddev, int mode, + struct block_device *bdev) { struct gendisk *disk = mddev->gendisk; struct md_rdev *rdev; mutex_lock(&mddev->open_mutex); - if (atomic_read(&mddev->openers) > is_open || + if (atomic_read(&mddev->openers) > !!bdev || mddev->sysfs_active) { printk("md: %s still in use.\n",mdname(mddev)); mutex_unlock(&mddev->open_mutex); return -EBUSY; } + if (bdev) + /* It is possible IO was issued on some other + * open file which was closed before we took ->open_mutex. + * As that was not the last close __blkdev_put will not + * have called sync_blockdev, so we must. + */ + sync_blockdev(bdev); if (mddev->pers) { if (mddev->ro) @@ -5239,7 +5249,7 @@ static void autorun_array(struct mddev *mddev) err = do_md_run(mddev); if (err) { printk(KERN_WARNING "md: do_md_run() returned %d\n", err); - do_md_stop(mddev, 0, 0); + do_md_stop(mddev, 0, NULL); } } @@ -6237,11 +6247,11 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, goto done_unlock; case STOP_ARRAY: - err = do_md_stop(mddev, 0, 1); + err = do_md_stop(mddev, 0, bdev); goto done_unlock; case STOP_ARRAY_RO: - err = md_set_readonly(mddev, 1); + err = md_set_readonly(mddev, bdev); goto done_unlock; case BLKROSET: diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index d1f74ab13966..d7add9d5bac2 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1821,8 +1821,14 @@ static void sync_request_write(struct mddev *mddev, struct r1bio *r1_bio) if (atomic_dec_and_test(&r1_bio->remaining)) { /* if we're here, all write(s) have completed, so clean up */ - md_done_sync(mddev, r1_bio->sectors, 1); - put_buf(r1_bio); + int s = r1_bio->sectors; + if (test_bit(R1BIO_MadeGood, &r1_bio->state) || + test_bit(R1BIO_WriteError, &r1_bio->state)) + reschedule_retry(r1_bio); + else { + put_buf(r1_bio); + md_done_sync(mddev, s, 1); + } } } diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 69ef0beae104..504da715a41a 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -157,6 +157,7 @@ static const struct sdhci_pci_fixes sdhci_ene_714 = { static const struct sdhci_pci_fixes sdhci_cafe = { .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | SDHCI_QUIRK_NO_BUSY_IRQ | + SDHCI_QUIRK_BROKEN_CARD_DETECTION | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, }; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index d83a4499249d..13e422b7c1e8 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1244,6 +1244,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) struct sdhci_host *host; bool present; unsigned long flags; + u32 tuning_opcode; host = mmc_priv(mmc); @@ -1295,8 +1296,12 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) */ if ((host->flags & SDHCI_NEEDS_RETUNING) && !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { + /* eMMC uses cmd21 while sd and sdio use cmd19 */ + tuning_opcode = mmc->card->type == MMC_TYPE_MMC ? + MMC_SEND_TUNING_BLOCK_HS200 : + MMC_SEND_TUNING_BLOCK; spin_unlock_irqrestore(&host->lock, flags); - sdhci_execute_tuning(mmc, mrq->cmd->opcode); + sdhci_execute_tuning(mmc, tuning_opcode); spin_lock_irqsave(&host->lock, flags); /* Restore original mmc_request structure */ diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 8a3054b84812..5de74e762021 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -325,6 +325,9 @@ static int ldisc_open(struct tty_struct *tty) sprintf(name, "cf%s", tty->name); dev = alloc_netdev(sizeof(*ser), name, caifdev_setup); + if (!dev) + return -ENOMEM; + ser = netdev_priv(dev); ser->tty = tty_kref_get(tty); ser->dev = dev; diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 1ef0c9275dee..65fe6324d817 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -267,7 +267,6 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) dev_warn(&pdev->dev, "stop mac failed\n"); atl1c_set_aspm(hw, false); netif_carrier_off(netdev); - netif_stop_queue(netdev); atl1c_phy_reset(hw); atl1c_phy_init(&adapter->hw); } else { diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 8297e2868736..b8ade570759e 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -5372,7 +5372,7 @@ bnx2_free_tx_skbs(struct bnx2 *bp) int k, last; if (skb == NULL) { - j++; + j = NEXT_TX_BD(j); continue; } @@ -5384,8 +5384,8 @@ bnx2_free_tx_skbs(struct bnx2 *bp) tx_buf->skb = NULL; last = tx_buf->nr_frags; - j++; - for (k = 0; k < last; k++, j++) { + j = NEXT_TX_BD(j); + for (k = 0; k < last; k++, j = NEXT_TX_BD(j)) { tx_buf = &txr->tx_buf_ring[TX_RING_IDX(j)]; dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(tx_buf, mapping), diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 1a1b29ff8143..689d2a1935bd 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -298,6 +298,7 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57795)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57762)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)}, {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)}, @@ -8948,8 +8949,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || tg3_flag(tp, 57765_PLUS)) { val = tr32(TG3_RDMA_RSRVCTRL_REG); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { + if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0) { val &= ~(TG3_RDMA_RSRVCTRL_TXMRGN_MASK | TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK | TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK); @@ -12255,10 +12255,12 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, { struct tg3 *tp = netdev_priv(dev); - if (!tp->hw_stats) + spin_lock_bh(&tp->lock); + if (!tp->hw_stats) { + spin_unlock_bh(&tp->lock); return &tp->net_stats_prev; + } - spin_lock_bh(&tp->lock); tg3_get_nstats(tp, stats); spin_unlock_bh(&tp->lock); diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index e7bed5303997..24381e1298e2 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -2065,10 +2065,9 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } - /* Steal sock reference for processing TX time stamps */ - swap(skb_new->sk, skb->sk); - swap(skb_new->destructor, skb->destructor); - kfree_skb(skb); + if (skb->sk) + skb_set_owner_w(skb_new, skb->sk); + consume_skb(skb); skb = skb_new; } diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index eab35cb398f2..6fbf75564daa 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5001,7 +5001,6 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp) { rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); tp->cur_tx = tp->dirty_tx = 0; - netdev_reset_queue(tp->dev); } static void rtl_reset_work(struct rtl8169_private *tp) @@ -5156,8 +5155,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, txd->opts2 = cpu_to_le32(opts[1]); - netdev_sent_queue(dev, skb->len); - skb_tx_timestamp(skb); wmb(); @@ -5254,16 +5251,9 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } -struct rtl_txc { - int packets; - int bytes; -}; - static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) { - struct rtl8169_stats *tx_stats = &tp->tx_stats; unsigned int dirty_tx, tx_left; - struct rtl_txc txc = { 0, 0 }; dirty_tx = tp->dirty_tx; smp_rmb(); @@ -5282,24 +5272,17 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, tp->TxDescArray + entry); if (status & LastFrag) { - struct sk_buff *skb = tx_skb->skb; - - txc.packets++; - txc.bytes += skb->len; - dev_kfree_skb(skb); + u64_stats_update_begin(&tp->tx_stats.syncp); + tp->tx_stats.packets++; + tp->tx_stats.bytes += tx_skb->skb->len; + u64_stats_update_end(&tp->tx_stats.syncp); + dev_kfree_skb(tx_skb->skb); tx_skb->skb = NULL; } dirty_tx++; tx_left--; } - u64_stats_update_begin(&tx_stats->syncp); - tx_stats->packets += txc.packets; - tx_stats->bytes += txc.bytes; - u64_stats_update_end(&tx_stats->syncp); - - netdev_completed_queue(dev, txc.packets, txc.bytes); - if (tp->dirty_tx != dirty_tx) { tp->dirty_tx = dirty_tx; /* Sync with rtl8169_start_xmit: diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 2391dae6c05b..965fa16588ca 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -358,6 +358,8 @@ static void tun_free_netdev(struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); + BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED, &tun->socket.flags)); + sk_release_kernel(tun->socket.sk); } @@ -1115,6 +1117,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun->flags = flags; tun->txflt.count = 0; tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); + set_bit(SOCK_EXTERNALLY_ALLOCATED, &tun->socket.flags); err = -ENOMEM; sk = sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, &tun_proto); @@ -1258,10 +1261,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, } #endif - if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) + if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) { if (copy_from_user(&ifr, argp, ifreq_len)) return -EFAULT; - + } else { + memset(&ifr, 0, sizeof(ifr)); + } if (cmd == TUNGETFEATURES) { /* Currently this just means: "what IFF flags are valid?". * This is needed because we never checked for invalid flags on diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index df2a2cf35a99..7a6ccd6c3b46 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -1302,7 +1302,7 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev, int retv; int length = 0; /* shut up GCC */ - urb = usb_alloc_urb(0, GFP_NOIO); + urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) return -ENOMEM; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index bef3f242434f..8be535f8f6d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -191,6 +191,7 @@ static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n", + sta->addr, (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? "static" : (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index baf691949c39..03560a8a8588 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -544,9 +544,9 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, /* * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid - * MCS index values for us are 0 to 7. + * MCS index values for us are 0 to 15. */ - if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 8)) { + if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) { sinfo->txrate.mcs = priv->tx_rate; sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; /* 40MHz rate */ diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 5601302d09ad..f388b65fbe90 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1137,6 +1137,8 @@ static struct usb_device_id rt2800usb_device_table[] = { #ifdef CONFIG_RT2800USB_RT33XX /* Belkin */ { USB_DEVICE(0x050d, 0x945b) }, + /* D-Link */ + { USB_DEVICE(0x2001, 0x3c17) }, /* Panasonic */ { USB_DEVICE(0x083a, 0xb511) }, /* Philips */ @@ -1237,7 +1239,6 @@ static struct usb_device_id rt2800usb_device_table[] = { /* D-Link */ { USB_DEVICE(0x07d1, 0x3c0b) }, { USB_DEVICE(0x07d1, 0x3c17) }, - { USB_DEVICE(0x2001, 0x3c17) }, /* Encore */ { USB_DEVICE(0x203d, 0x14a1) }, /* Gemtek */ diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 28fc5fb8057b..46f7917fed5c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -3344,21 +3344,21 @@ void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw) switch (rtlhal->macphymode) { case DUALMAC_SINGLEPHY: rtlphy->rf_type = RF_2T2R; - rtlhal->version |= CHIP_92D_SINGLEPHY; + rtlhal->version |= RF_TYPE_2T2R; rtlhal->bandset = BAND_ON_BOTH; rtlhal->current_bandtype = BAND_ON_2_4G; break; case SINGLEMAC_SINGLEPHY: rtlphy->rf_type = RF_2T2R; - rtlhal->version |= CHIP_92D_SINGLEPHY; + rtlhal->version |= RF_TYPE_2T2R; rtlhal->bandset = BAND_ON_BOTH; rtlhal->current_bandtype = BAND_ON_2_4G; break; case DUALMAC_DUALPHY: rtlphy->rf_type = RF_1T1R; - rtlhal->version &= (~CHIP_92D_SINGLEPHY); + rtlhal->version &= RF_TYPE_1T1R; /* Now we let MAC0 run on 5G band. */ if (rtlhal->interfaceindex == 0) { rtlhal->bandset = BAND_ON_5G; diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index a6049d7d51b3..aa970fc18a21 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -131,15 +131,19 @@ static u32 _usb_read_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len) u8 request; u16 wvalue; u16 index; - __le32 *data = &rtlpriv->usb_data[rtlpriv->usb_data_index]; + __le32 *data; + unsigned long flags; + spin_lock_irqsave(&rtlpriv->locks.usb_lock, flags); + if (++rtlpriv->usb_data_index >= RTL_USB_MAX_RX_COUNT) + rtlpriv->usb_data_index = 0; + data = &rtlpriv->usb_data[rtlpriv->usb_data_index]; + spin_unlock_irqrestore(&rtlpriv->locks.usb_lock, flags); request = REALTEK_USB_VENQT_CMD_REQ; index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ wvalue = (u16)addr; _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len); - if (++rtlpriv->usb_data_index >= RTL_USB_MAX_RX_COUNT) - rtlpriv->usb_data_index = 0; return le32_to_cpu(*data); } @@ -951,6 +955,10 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, GFP_KERNEL); if (!rtlpriv->usb_data) return -ENOMEM; + + /* this spin lock must be initialized early */ + spin_lock_init(&rtlpriv->locks.usb_lock); + rtlpriv->usb_data_index = 0; init_completion(&rtlpriv->firmware_loading_complete); SET_IEEE80211_DEV(hw, &intf->dev); diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 28ebc69218a3..717d3bad17d6 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1555,6 +1555,7 @@ struct rtl_locks { spinlock_t rf_ps_lock; spinlock_t rf_lock; spinlock_t waitq_lock; + spinlock_t usb_lock; /*Dual mac*/ spinlock_t cck_and_rw_pagea_lock; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index f85921607686..951b6cf086af 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1818,6 +1818,8 @@ static void qeth_l3_free_vlan_addresses4(struct qeth_card *card, QETH_CARD_TEXT(card, 4, "frvaddr4"); netdev = __vlan_find_dev_deep(card->dev, vid); + if (!netdev) + return; in_dev = in_dev_get(netdev); if (!in_dev) return; @@ -1846,6 +1848,8 @@ static void qeth_l3_free_vlan_addresses6(struct qeth_card *card, QETH_CARD_TEXT(card, 4, "frvaddr6"); netdev = __vlan_find_dev_deep(card->dev, vid); + if (!netdev) + return; in6_dev = in6_dev_get(netdev); if (!in6_dev) return; diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index a3a056a9db67..b48c24f7d21a 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -290,6 +290,7 @@ static void scsi_host_dev_release(struct device *dev) struct Scsi_Host *shost = dev_to_shost(dev); struct device *parent = dev->parent; struct request_queue *q; + void *queuedata; scsi_proc_hostdir_rm(shost->hostt); @@ -299,9 +300,9 @@ static void scsi_host_dev_release(struct device *dev) destroy_workqueue(shost->work_q); q = shost->uspace_req_q; if (q) { - kfree(q->queuedata); - q->queuedata = NULL; - scsi_free_queue(q); + queuedata = q->queuedata; + blk_cleanup_queue(q); + kfree(queuedata); } scsi_destroy_command_freelist(shost); diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index caa0525d2523..101b28e61c6f 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -868,7 +868,7 @@ static struct domain_device *sas_ex_discover_end_dev( } /* See if this phy is part of a wide port */ -static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) +static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id) { struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id]; int i; @@ -884,11 +884,11 @@ static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) sas_port_add_phy(ephy->port, phy->phy); phy->port = ephy->port; phy->phy_state = PHY_DEVICE_DISCOVERED; - return 0; + return true; } } - return -ENODEV; + return false; } static struct domain_device *sas_ex_discover_expander( @@ -1030,8 +1030,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) return res; } - res = sas_ex_join_wide_port(dev, phy_id); - if (!res) { + if (sas_ex_join_wide_port(dev, phy_id)) { SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", phy_id, SAS_ADDR(ex_phy->attached_sas_addr)); return res; @@ -1077,8 +1076,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) == SAS_ADDR(child->sas_addr)) { ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED; - res = sas_ex_join_wide_port(dev, i); - if (!res) + if (sas_ex_join_wide_port(dev, i)) SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr)); @@ -1943,32 +1941,20 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) { struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id]; struct domain_device *child; - bool found = false; - int res, i; + int res; SAS_DPRINTK("ex %016llx phy%d new device attached\n", SAS_ADDR(dev->sas_addr), phy_id); res = sas_ex_phy_discover(dev, phy_id); if (res) - goto out; - /* to support the wide port inserted */ - for (i = 0; i < dev->ex_dev.num_phys; i++) { - struct ex_phy *ex_phy_temp = &dev->ex_dev.ex_phy[i]; - if (i == phy_id) - continue; - if (SAS_ADDR(ex_phy_temp->attached_sas_addr) == - SAS_ADDR(ex_phy->attached_sas_addr)) { - found = true; - break; - } - } - if (found) { - sas_ex_join_wide_port(dev, phy_id); + return res; + + if (sas_ex_join_wide_port(dev, phy_id)) return 0; - } + res = sas_ex_discover_devices(dev, phy_id); - if (!res) - goto out; + if (res) + return res; list_for_each_entry(child, &dev->ex_dev.children, siblings) { if (SAS_ADDR(child->sas_addr) == SAS_ADDR(ex_phy->attached_sas_addr)) { @@ -1978,7 +1964,6 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) break; } } -out: return res; } @@ -2109,9 +2094,7 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) struct domain_device *dev = NULL; res = sas_find_bcast_dev(port_dev, &dev); - if (res) - goto out; - if (dev) { + while (res == 0 && dev) { struct expander_device *ex = &dev->ex_dev; int i = 0, phy_id; @@ -2123,8 +2106,10 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) res = sas_rediscover(dev, phy_id); i = phy_id + 1; } while (i < ex->num_phys); + + dev = NULL; + res = sas_find_bcast_dev(port_dev, &dev); } -out: return res; } diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 386f0c53bea7..cc8dc8cc6d6f 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1687,6 +1687,20 @@ static void scsi_restart_operations(struct Scsi_Host *shost) * requests are started. */ scsi_run_host_queues(shost); + + /* + * if eh is active and host_eh_scheduled is pending we need to re-run + * recovery. we do this check after scsi_run_host_queues() to allow + * everything pent up since the last eh run a chance to make forward + * progress before we sync again. Either we'll immediately re-run + * recovery or scsi_device_unbusy() will wake us again when these + * pending commands complete. + */ + spin_lock_irqsave(shost->host_lock, flags); + if (shost->host_eh_scheduled) + if (scsi_host_set_state(shost, SHOST_RECOVERY)) + WARN_ON(scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)); + spin_unlock_irqrestore(shost->host_lock, flags); } /** diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 4037fd5b1e00..19291463c554 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -406,10 +406,6 @@ static void scsi_run_queue(struct request_queue *q) LIST_HEAD(starved_list); unsigned long flags; - /* if the device is dead, sdev will be NULL, so no queue to run */ - if (!sdev) - return; - shost = sdev->host; if (scsi_target(sdev)->single_lun) scsi_single_lun_run(sdev); @@ -483,15 +479,26 @@ void scsi_requeue_run_queue(struct work_struct *work) */ static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd) { + struct scsi_device *sdev = cmd->device; struct request *req = cmd->request; unsigned long flags; + /* + * We need to hold a reference on the device to avoid the queue being + * killed after the unlock and before scsi_run_queue is invoked which + * may happen because scsi_unprep_request() puts the command which + * releases its reference on the device. + */ + get_device(&sdev->sdev_gendev); + spin_lock_irqsave(q->queue_lock, flags); scsi_unprep_request(req); blk_requeue_request(q, req); spin_unlock_irqrestore(q->queue_lock, flags); scsi_run_queue(q); + + put_device(&sdev->sdev_gendev); } void scsi_next_command(struct scsi_cmnd *cmd) @@ -1370,16 +1377,16 @@ static inline int scsi_host_queue_ready(struct request_queue *q, * may be changed after request stacking drivers call the function, * regardless of taking lock or not. * - * When scsi can't dispatch I/Os anymore and needs to kill I/Os - * (e.g. !sdev), scsi needs to return 'not busy'. - * Otherwise, request stacking drivers may hold requests forever. + * When scsi can't dispatch I/Os anymore and needs to kill I/Os scsi + * needs to return 'not busy'. Otherwise, request stacking drivers + * may hold requests forever. */ static int scsi_lld_busy(struct request_queue *q) { struct scsi_device *sdev = q->queuedata; struct Scsi_Host *shost; - if (!sdev) + if (blk_queue_dead(q)) return 0; shost = sdev->host; @@ -1490,12 +1497,6 @@ static void scsi_request_fn(struct request_queue *q) struct scsi_cmnd *cmd; struct request *req; - if (!sdev) { - while ((req = blk_peek_request(q)) != NULL) - scsi_kill_request(req, q); - return; - } - if(!get_device(&sdev->sdev_gendev)) /* We must be tearing the block queue down already */ return; @@ -1697,20 +1698,6 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) return q; } -void scsi_free_queue(struct request_queue *q) -{ - unsigned long flags; - - WARN_ON(q->queuedata); - - /* cause scsi_request_fn() to kill all non-finished requests */ - spin_lock_irqsave(q->queue_lock, flags); - q->request_fn(q); - spin_unlock_irqrestore(q->queue_lock, flags); - - blk_cleanup_queue(q); -} - /* * Function: scsi_block_requests() * diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index be4fa6d179b1..fd9f57fd2102 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -84,7 +84,6 @@ extern void scsi_next_command(struct scsi_cmnd *cmd); extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); extern void scsi_run_host_queues(struct Scsi_Host *shost); extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev); -extern void scsi_free_queue(struct request_queue *q); extern int scsi_init_queue(void); extern void scsi_exit_queue(void); struct request_queue; diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 01b03744f1f9..8906557d2a24 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1714,6 +1714,9 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost) { struct scsi_device *sdev; shost_for_each_device(sdev, shost) { + /* target removed before the device could be added */ + if (sdev->sdev_state == SDEV_DEL) + continue; if (!scsi_host_scan_allowed(shost) || scsi_sysfs_add_sdev(sdev) != 0) __scsi_remove_device(sdev); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 04c2a278076e..bb7c4828acc0 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -971,11 +971,8 @@ void __scsi_remove_device(struct scsi_device *sdev) sdev->host->hostt->slave_destroy(sdev); transport_destroy_device(dev); - /* cause the request function to reject all I/O requests */ - sdev->request_queue->queuedata = NULL; - /* Freeing the queue signals to block that we're done */ - scsi_free_queue(sdev->request_queue); + blk_cleanup_queue(sdev->request_queue); put_device(dev); } @@ -1000,7 +997,6 @@ static void __scsi_remove_target(struct scsi_target *starget) struct scsi_device *sdev; spin_lock_irqsave(shost->host_lock, flags); - starget->reap_ref++; restart: list_for_each_entry(sdev, &shost->__devices, siblings) { if (sdev->channel != starget->channel || @@ -1014,14 +1010,6 @@ static void __scsi_remove_target(struct scsi_target *starget) goto restart; } spin_unlock_irqrestore(shost->host_lock, flags); - scsi_target_reap(starget); -} - -static int __remove_child (struct device * dev, void * data) -{ - if (scsi_is_target_device(dev)) - __scsi_remove_target(to_scsi_target(dev)); - return 0; } /** @@ -1034,14 +1022,34 @@ static int __remove_child (struct device * dev, void * data) */ void scsi_remove_target(struct device *dev) { - if (scsi_is_target_device(dev)) { - __scsi_remove_target(to_scsi_target(dev)); - return; + struct Scsi_Host *shost = dev_to_shost(dev->parent); + struct scsi_target *starget, *found; + unsigned long flags; + + restart: + found = NULL; + spin_lock_irqsave(shost->host_lock, flags); + list_for_each_entry(starget, &shost->__targets, siblings) { + if (starget->state == STARGET_DEL) + continue; + if (starget->dev.parent == dev || &starget->dev == dev) { + found = starget; + found->reap_ref++; + break; + } } + spin_unlock_irqrestore(shost->host_lock, flags); - get_device(dev); - device_for_each_child(dev, NULL, __remove_child); - put_device(dev); + if (found) { + __scsi_remove_target(found); + scsi_target_reap(found); + /* in the case where @dev has multiple starget children, + * continue removing. + * + * FIXME: does such a case exist? + */ + goto restart; + } } EXPORT_SYMBOL(scsi_remove_target); diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 400ae2121a2a..469eb28e8328 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -489,6 +489,11 @@ static void giveback(struct pl022 *pl022) pl022->cur_transfer = NULL; pl022->cur_chip = NULL; spi_finalize_current_message(pl022->master); + + /* disable the SPI/SSP operation */ + writew((readw(SSP_CR1(pl022->virtbase)) & + (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); + } /** diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 917461c66014..175b3c94d5a7 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -426,12 +426,6 @@ static struct page *find_get_zspage(struct size_class *class) } -/* - * If this becomes a separate module, register zs_init() with - * module_init(), zs_exit with module_exit(), and remove zs_initialized -*/ -static int zs_initialized; - static int zs_cpu_notifier(struct notifier_block *nb, unsigned long action, void *pcpu) { @@ -490,7 +484,7 @@ fail: struct zs_pool *zs_create_pool(const char *name, gfp_t flags) { - int i, error, ovhd_size; + int i, ovhd_size; struct zs_pool *pool; if (!name) @@ -517,28 +511,9 @@ struct zs_pool *zs_create_pool(const char *name, gfp_t flags) } - /* - * If this becomes a separate module, register zs_init with - * module_init, and remove this block - */ - if (!zs_initialized) { - error = zs_init(); - if (error) - goto cleanup; - zs_initialized = 1; - } - pool->flags = flags; pool->name = name; - error = 0; /* Success */ - -cleanup: - if (error) { - zs_destroy_pool(pool); - pool = NULL; - } - return pool; } EXPORT_SYMBOL_GPL(zs_create_pool); @@ -749,3 +724,9 @@ u64 zs_get_total_size_bytes(struct zs_pool *pool) return npages << PAGE_SHIFT; } EXPORT_SYMBOL_GPL(zs_get_total_size_bytes); + +module_init(zs_init); +module_exit(zs_exit); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Nitin Gupta <ngupta@vflare.org>"); diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 8b1d5e62ed40..e326d17e05a8 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -427,19 +427,8 @@ int iscsit_reset_np_thread( int iscsit_del_np_comm(struct iscsi_np *np) { - if (!np->np_socket) - return 0; - - /* - * Some network transports allocate their own struct sock->file, - * see if we need to free any additional allocated resources. - */ - if (np->np_flags & NPF_SCTP_STRUCT_FILE) { - kfree(np->np_socket->file); - np->np_socket->file = NULL; - } - - sock_release(np->np_socket); + if (np->np_socket) + sock_release(np->np_socket); return 0; } @@ -4094,13 +4083,8 @@ int iscsit_close_connection( kfree(conn->conn_ops); conn->conn_ops = NULL; - if (conn->sock) { - if (conn->conn_flags & CONNFLAG_SCTP_STRUCT_FILE) { - kfree(conn->sock->file); - conn->sock->file = NULL; - } + if (conn->sock) sock_release(conn->sock); - } conn->thread_set = NULL; pr_debug("Moving to TARG_CONN_STATE_FREE.\n"); diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 2aaee7efa683..d1c4bc22cca4 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -224,7 +224,6 @@ enum iscsi_timer_flags_table { /* Used for struct iscsi_np->np_flags */ enum np_flags_table { NPF_IP_NETWORK = 0x00, - NPF_SCTP_STRUCT_FILE = 0x01 /* Bugfix */ }; /* Used for struct iscsi_np->np_thread_state */ @@ -511,7 +510,6 @@ struct iscsi_conn { u16 local_port; int net_size; u32 auth_id; -#define CONNFLAG_SCTP_STRUCT_FILE 0x01 u32 conn_flags; /* Used for iscsi_tx_login_rsp() */ u32 login_itt; diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index a3656c9903a1..ae304248c8c2 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -795,22 +795,6 @@ int iscsi_target_setup_login_socket( } np->np_socket = sock; /* - * The SCTP stack needs struct socket->file. - */ - if ((np->np_network_transport == ISCSI_SCTP_TCP) || - (np->np_network_transport == ISCSI_SCTP_UDP)) { - if (!sock->file) { - sock->file = kzalloc(sizeof(struct file), GFP_KERNEL); - if (!sock->file) { - pr_err("Unable to allocate struct" - " file for SCTP\n"); - ret = -ENOMEM; - goto fail; - } - np->np_flags |= NPF_SCTP_STRUCT_FILE; - } - } - /* * Setup the np->np_sockaddr from the passed sockaddr setup * in iscsi_target_configfs.c code.. */ @@ -869,21 +853,15 @@ int iscsi_target_setup_login_socket( fail: np->np_socket = NULL; - if (sock) { - if (np->np_flags & NPF_SCTP_STRUCT_FILE) { - kfree(sock->file); - sock->file = NULL; - } - + if (sock) sock_release(sock); - } return ret; } static int __iscsi_target_login_thread(struct iscsi_np *np) { u8 buffer[ISCSI_HDR_LEN], iscsi_opcode, zero_tsih = 0; - int err, ret = 0, set_sctp_conn_flag, stop; + int err, ret = 0, stop; struct iscsi_conn *conn = NULL; struct iscsi_login *login; struct iscsi_portal_group *tpg = NULL; @@ -894,7 +872,6 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) struct sockaddr_in6 sock_in6; flush_signals(current); - set_sctp_conn_flag = 0; sock = np->np_socket; spin_lock_bh(&np->np_thread_lock); @@ -917,35 +894,12 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) spin_unlock_bh(&np->np_thread_lock); goto out; } - /* - * The SCTP stack needs struct socket->file. - */ - if ((np->np_network_transport == ISCSI_SCTP_TCP) || - (np->np_network_transport == ISCSI_SCTP_UDP)) { - if (!new_sock->file) { - new_sock->file = kzalloc( - sizeof(struct file), GFP_KERNEL); - if (!new_sock->file) { - pr_err("Unable to allocate struct" - " file for SCTP\n"); - sock_release(new_sock); - /* Get another socket */ - return 1; - } - set_sctp_conn_flag = 1; - } - } - iscsi_start_login_thread_timer(np); conn = kzalloc(sizeof(struct iscsi_conn), GFP_KERNEL); if (!conn) { pr_err("Could not allocate memory for" " new connection\n"); - if (set_sctp_conn_flag) { - kfree(new_sock->file); - new_sock->file = NULL; - } sock_release(new_sock); /* Get another socket */ return 1; @@ -955,9 +909,6 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) conn->conn_state = TARG_CONN_STATE_FREE; conn->sock = new_sock; - if (set_sctp_conn_flag) - conn->conn_flags |= CONNFLAG_SCTP_STRUCT_FILE; - pr_debug("Moving to TARG_CONN_STATE_XPT_UP.\n"); conn->conn_state = TARG_CONN_STATE_XPT_UP; @@ -1205,13 +1156,8 @@ old_sess_out: iscsi_release_param_list(conn->param_list); conn->param_list = NULL; } - if (conn->sock) { - if (conn->conn_flags & CONNFLAG_SCTP_STRUCT_FILE) { - kfree(conn->sock->file); - conn->sock->file = NULL; - } + if (conn->sock) sock_release(conn->sock); - } kfree(conn); if (tpg) { diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 30a67707036f..fa323f8aa171 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c @@ -1107,7 +1107,7 @@ int target_emulate_write_same(struct se_task *task) if (num_blocks != 0) range = num_blocks; else - range = (dev->transport->get_blocks(dev) - lba); + range = (dev->transport->get_blocks(dev) - lba) + 1; pr_debug("WRITE_SAME UNMAP: LBA: %llu Range: %llu\n", (unsigned long long)lba, (unsigned long long)range); diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index c3148b10b4b3..89d10e6a82ee 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -2038,7 +2038,7 @@ static int __core_scsi3_write_aptpl_to_file( if (IS_ERR(file) || !file || !file->f_dentry) { pr_err("filp_open(%s) for APTPL metadata" " failed\n", path); - return (PTR_ERR(file) < 0 ? PTR_ERR(file) : -ENOENT); + return IS_ERR(file) ? PTR_ERR(file) : -ENOENT; } iov[0].iov_base = &buf[0]; @@ -3826,7 +3826,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task) " SPC-2 reservation is held, returning" " RESERVATION_CONFLICT\n"); cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - ret = EINVAL; + ret = -EINVAL; goto out; } @@ -3836,7 +3836,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) */ if (!cmd->se_sess) { cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + ret = -EINVAL; + goto out; } if (cmd->data_length < 24) { diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 443704f84fd5..0686d61adeae 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1976,6 +1976,7 @@ void transport_generic_request_failure(struct se_cmd *cmd) case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE: case TCM_UNKNOWN_MODE_PAGE: case TCM_WRITE_PROTECTED: + case TCM_ADDRESS_OUT_OF_RANGE: case TCM_CHECK_CONDITION_ABORT_CMD: case TCM_CHECK_CONDITION_UNIT_ATTENTION: case TCM_CHECK_CONDITION_NOT_READY: @@ -4656,6 +4657,15 @@ int transport_send_check_condition_and_sense( /* WRITE PROTECTED */ buffer[offset+SPC_ASC_KEY_OFFSET] = 0x27; break; + case TCM_ADDRESS_OUT_OF_RANGE: + /* CURRENT ERROR */ + buffer[offset] = 0x70; + buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + /* ILLEGAL REQUEST */ + buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + /* LOGICAL BLOCK ADDRESS OUT OF RANGE */ + buffer[offset+SPC_ASC_KEY_OFFSET] = 0x21; + break; case TCM_CHECK_CONDITION_UNIT_ATTENTION: /* CURRENT ERROR */ buffer[offset] = 0x70; diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index a375f257aabc..da90f647695e 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -240,6 +240,8 @@ u32 ft_get_task_tag(struct se_cmd *se_cmd) { struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd); + if (cmd->aborted) + return ~0; return fc_seq_exch(cmd->seq)->rxid; } diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 4e577728ead6..404413b0b938 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1615,10 +1615,14 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) void __user *addr = as->userurb; unsigned int i; - if (as->userbuffer && urb->actual_length) - if (copy_to_user(as->userbuffer, urb->transfer_buffer, - urb->actual_length)) + if (as->userbuffer && urb->actual_length) { + if (urb->number_of_packets > 0) /* Isochronous */ + i = urb->transfer_buffer_length; + else /* Non-Isoc */ + i = urb->actual_length; + if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) return -EFAULT; + } if (put_user(as->status, &userurb->status)) return -EFAULT; if (put_user(urb->actual_length, &userurb->actual_length)) diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 1fc8f1249806..347bb058e1ee 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c @@ -450,7 +450,7 @@ static int dbgp_ehci_startup(void) writel(FLAG_CF, &ehci_regs->configured_flag); /* Wait until the controller is no longer halted */ - loop = 10; + loop = 1000; do { status = readl(&ehci_regs->status); if (!(status & STS_HALT)) diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index c8702c8eab55..18bf28cb2851 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -816,12 +816,6 @@ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], SET_ETHTOOL_OPS(net, &ops); - /* two kinds of host-initiated state changes: - * - iff DATA transfer is active, carrier is "on" - * - tx queueing enabled if open *and* carrier is "on" - */ - netif_carrier_off(net); - dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); SET_NETDEV_DEVTYPE(net, &gadget_type); @@ -835,6 +829,12 @@ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], INFO(dev, "HOST MAC %pM\n", dev->host_mac); the_dev = dev; + + /* two kinds of host-initiated state changes: + * - iff DATA transfer is active, carrier is "on" + * - tx queueing enabled if open *and* carrier is "on" + */ + netif_carrier_off(net); } return status; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 49484b39cc09..ae1a4b8c6893 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -936,6 +936,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 8ec8a6e66f50..f98ba40352c1 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -58,9 +58,6 @@ enum { SUBMIT_DATA_OUT_URB = (1 << 5), ALLOC_CMD_URB = (1 << 6), SUBMIT_CMD_URB = (1 << 7), - COMPLETED_DATA_IN = (1 << 8), - COMPLETED_DATA_OUT = (1 << 9), - DATA_COMPLETES_CMD = (1 << 10), }; /* Overrides scsi_pointer */ @@ -114,7 +111,6 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) { struct sense_iu *sense_iu = urb->transfer_buffer; struct scsi_device *sdev = cmnd->device; - struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; if (urb->actual_length > 16) { unsigned len = be16_to_cpup(&sense_iu->len); @@ -132,15 +128,13 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - if (!(cmdinfo->state & DATA_COMPLETES_CMD)) - cmnd->scsi_done(cmnd); + cmnd->scsi_done(cmnd); } static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) { struct sense_iu_old *sense_iu = urb->transfer_buffer; struct scsi_device *sdev = cmnd->device; - struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; if (urb->actual_length > 8) { unsigned len = be16_to_cpup(&sense_iu->len) - 2; @@ -158,8 +152,7 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - if (!(cmdinfo->state & DATA_COMPLETES_CMD)) - cmnd->scsi_done(cmnd); + cmnd->scsi_done(cmnd); } static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, @@ -184,7 +177,6 @@ static void uas_stat_cmplt(struct urb *urb) struct Scsi_Host *shost = urb->context; struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; struct scsi_cmnd *cmnd; - struct uas_cmd_info *cmdinfo; u16 tag; int ret; @@ -210,32 +202,12 @@ static void uas_stat_cmplt(struct urb *urb) dev_err(&urb->dev->dev, "failed submit status urb\n"); return; } - cmdinfo = (void *)&cmnd->SCp; switch (iu->iu_id) { case IU_ID_STATUS: if (devinfo->cmnd == cmnd) devinfo->cmnd = NULL; - if (!(cmdinfo->state & COMPLETED_DATA_IN) && - cmdinfo->data_in_urb) { - if (devinfo->use_streams) { - cmdinfo->state |= DATA_COMPLETES_CMD; - usb_unlink_urb(cmdinfo->data_in_urb); - } else { - usb_free_urb(cmdinfo->data_in_urb); - } - } - if (!(cmdinfo->state & COMPLETED_DATA_OUT) && - cmdinfo->data_out_urb) { - if (devinfo->use_streams) { - cmdinfo->state |= DATA_COMPLETES_CMD; - usb_unlink_urb(cmdinfo->data_in_urb); - } else { - usb_free_urb(cmdinfo->data_out_urb); - } - } - if (urb->actual_length < 16) devinfo->uas_sense_old = 1; if (devinfo->uas_sense_old) @@ -264,59 +236,27 @@ static void uas_stat_cmplt(struct urb *urb) dev_err(&urb->dev->dev, "failed submit status urb\n"); } -static void uas_data_out_cmplt(struct urb *urb) -{ - struct scsi_cmnd *cmnd = urb->context; - struct scsi_data_buffer *sdb = scsi_out(cmnd); - struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; - - cmdinfo->state |= COMPLETED_DATA_OUT; - - sdb->resid = sdb->length - urb->actual_length; - usb_free_urb(urb); - - if (cmdinfo->state & DATA_COMPLETES_CMD) - cmnd->scsi_done(cmnd); -} - -static void uas_data_in_cmplt(struct urb *urb) +static void uas_data_cmplt(struct urb *urb) { - struct scsi_cmnd *cmnd = urb->context; - struct scsi_data_buffer *sdb = scsi_in(cmnd); - struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; - - cmdinfo->state |= COMPLETED_DATA_IN; - + struct scsi_data_buffer *sdb = urb->context; sdb->resid = sdb->length - urb->actual_length; usb_free_urb(urb); - - if (cmdinfo->state & DATA_COMPLETES_CMD) - cmnd->scsi_done(cmnd); } static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, - unsigned int pipe, struct scsi_cmnd *cmnd, - enum dma_data_direction dir) + unsigned int pipe, u16 stream_id, + struct scsi_data_buffer *sdb, + enum dma_data_direction dir) { - struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; struct usb_device *udev = devinfo->udev; struct urb *urb = usb_alloc_urb(0, gfp); - struct scsi_data_buffer *sdb; - usb_complete_t complete_fn; - u16 stream_id = cmdinfo->stream; if (!urb) goto out; - if (dir == DMA_FROM_DEVICE) { - sdb = scsi_in(cmnd); - complete_fn = uas_data_in_cmplt; - } else { - sdb = scsi_out(cmnd); - complete_fn = uas_data_out_cmplt; - } - usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, - complete_fn, cmnd); - urb->stream_id = stream_id; + usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, uas_data_cmplt, + sdb); + if (devinfo->use_streams) + urb->stream_id = stream_id; urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0; urb->sg = sdb->table.sgl; out: @@ -418,8 +358,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & ALLOC_DATA_IN_URB) { cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp, - devinfo->data_in_pipe, cmnd, - DMA_FROM_DEVICE); + devinfo->data_in_pipe, cmdinfo->stream, + scsi_in(cmnd), DMA_FROM_DEVICE); if (!cmdinfo->data_in_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_DATA_IN_URB; @@ -436,8 +376,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & ALLOC_DATA_OUT_URB) { cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp, - devinfo->data_out_pipe, cmnd, - DMA_TO_DEVICE); + devinfo->data_out_pipe, cmdinfo->stream, + scsi_out(cmnd), DMA_TO_DEVICE); if (!cmdinfo->data_out_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_DATA_OUT_URB; |