diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-16 08:06:26 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-16 08:06:26 +0300 |
commit | 72f02ba66bd83b54054da20eae550123de84da6f (patch) | |
tree | 96a8360400e040aa2e38e7352594dbbc485461db /drivers/scsi/csiostor/csio_hw.c | |
parent | db06f826ec12bf0701ea7fc0a3c0aa00b84417c8 (diff) | |
parent | 51372570ac3c919b036e760f4ca449e81cf8e995 (diff) | |
download | linux-72f02ba66bd83b54054da20eae550123de84da6f.tar.xz |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This is mostly updates to the usual drivers: mpt3sas, lpfc, qla2xxx,
hisi_sas, smartpqi, megaraid_sas, arcmsr.
In addition, with the continuing absence of Nic we have target updates
for tcmu and target core (all with reviews and acks).
The biggest observable change is going to be that we're (again) trying
to switch to mulitqueue as the default (a user can still override the
setting on the kernel command line).
Other major core stuff is the removal of the remaining Microchannel
drivers, an update of the internal timers and some reworks of
completion and result handling"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (203 commits)
scsi: core: use blk_mq_run_hw_queues in scsi_kick_queue
scsi: ufs: remove unnecessary query(DM) UPIU trace
scsi: qla2xxx: Fix issue reported by static checker for qla2x00_els_dcmd2_sp_done()
scsi: aacraid: Spelling fix in comment
scsi: mpt3sas: Fix calltrace observed while running IO & reset
scsi: aic94xx: fix an error code in aic94xx_init()
scsi: st: remove redundant pointer STbuffer
scsi: qla2xxx: Update driver version to 10.00.00.08-k
scsi: qla2xxx: Migrate NVME N2N handling into state machine
scsi: qla2xxx: Save frame payload size from ICB
scsi: qla2xxx: Fix stalled relogin
scsi: qla2xxx: Fix race between switch cmd completion and timeout
scsi: qla2xxx: Fix Management Server NPort handle reservation logic
scsi: qla2xxx: Flush mailbox commands on chip reset
scsi: qla2xxx: Fix unintended Logout
scsi: qla2xxx: Fix session state stuck in Get Port DB
scsi: qla2xxx: Fix redundant fc_rport registration
scsi: qla2xxx: Silent erroneous message
scsi: qla2xxx: Prevent sysfs access when chip is down
scsi: qla2xxx: Add longer window for chip reset
...
Diffstat (limited to 'drivers/scsi/csiostor/csio_hw.c')
-rw-r--r-- | drivers/scsi/csiostor/csio_hw.c | 115 |
1 files changed, 102 insertions, 13 deletions
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c index a10cf25ee7f9..23d07e9f87d0 100644 --- a/drivers/scsi/csiostor/csio_hw.c +++ b/drivers/scsi/csiostor/csio_hw.c @@ -761,27 +761,116 @@ out: static int csio_hw_get_flash_params(struct csio_hw *hw) { + /* Table for non-Numonix supported flash parts. Numonix parts are left + * to the preexisting code. All flash parts have 64KB sectors. + */ + static struct flash_desc { + u32 vendor_and_model_id; + u32 size_mb; + } supported_flash[] = { + { 0x150201, 4 << 20 }, /* Spansion 4MB S25FL032P */ + }; + + u32 part, manufacturer; + u32 density, size = 0; + u32 flashid = 0; int ret; - uint32_t info = 0; ret = csio_hw_sf1_write(hw, 1, 1, 0, SF_RD_ID); if (!ret) - ret = csio_hw_sf1_read(hw, 3, 0, 1, &info); + ret = csio_hw_sf1_read(hw, 3, 0, 1, &flashid); csio_wr_reg32(hw, 0, SF_OP_A); /* unlock SF */ - if (ret != 0) + if (ret) return ret; - if ((info & 0xff) != 0x20) /* not a Numonix flash */ - return -EINVAL; - info >>= 16; /* log2 of size */ - if (info >= 0x14 && info < 0x18) - hw->params.sf_nsec = 1 << (info - 16); - else if (info == 0x18) - hw->params.sf_nsec = 64; - else - return -EINVAL; - hw->params.sf_size = 1 << info; + /* Check to see if it's one of our non-standard supported Flash parts. + */ + for (part = 0; part < ARRAY_SIZE(supported_flash); part++) + if (supported_flash[part].vendor_and_model_id == flashid) { + hw->params.sf_size = supported_flash[part].size_mb; + hw->params.sf_nsec = + hw->params.sf_size / SF_SEC_SIZE; + goto found; + } + + /* Decode Flash part size. The code below looks repetative with + * common encodings, but that's not guaranteed in the JEDEC + * specification for the Read JADEC ID command. The only thing that + * we're guaranteed by the JADEC specification is where the + * Manufacturer ID is in the returned result. After that each + * Manufacturer ~could~ encode things completely differently. + * Note, all Flash parts must have 64KB sectors. + */ + manufacturer = flashid & 0xff; + switch (manufacturer) { + case 0x20: { /* Micron/Numonix */ + /* This Density -> Size decoding table is taken from Micron + * Data Sheets. + */ + density = (flashid >> 16) & 0xff; + switch (density) { + case 0x14 ... 0x19: /* 1MB - 32MB */ + size = 1 << density; + break; + case 0x20: /* 64MB */ + size = 1 << 26; + break; + case 0x21: /* 128MB */ + size = 1 << 27; + break; + case 0x22: /* 256MB */ + size = 1 << 28; + } + break; + } + case 0x9d: { /* ISSI -- Integrated Silicon Solution, Inc. */ + /* This Density -> Size decoding table is taken from ISSI + * Data Sheets. + */ + density = (flashid >> 16) & 0xff; + switch (density) { + case 0x16: /* 32 MB */ + size = 1 << 25; + break; + case 0x17: /* 64MB */ + size = 1 << 26; + } + break; + } + case 0xc2: /* Macronix */ + case 0xef: /* Winbond */ { + /* This Density -> Size decoding table is taken from + * Macronix and Winbond Data Sheets. + */ + density = (flashid >> 16) & 0xff; + switch (density) { + case 0x17: /* 8MB */ + case 0x18: /* 16MB */ + size = 1 << density; + } + } + } + + /* If we didn't recognize the FLASH part, that's no real issue: the + * Hardware/Software contract says that Hardware will _*ALWAYS*_ + * use a FLASH part which is at least 4MB in size and has 64KB + * sectors. The unrecognized FLASH part is likely to be much larger + * than 4MB, but that's all we really need. + */ + if (size == 0) { + csio_warn(hw, "Unknown Flash Part, ID = %#x, assuming 4MB\n", + flashid); + size = 1 << 22; + } + + /* Store decoded Flash size */ + hw->params.sf_size = size; + hw->params.sf_nsec = size / SF_SEC_SIZE; +found: + if (hw->params.sf_size < FLASH_MIN_SIZE) + csio_warn(hw, "WARNING: Flash Part ID %#x, size %#x < %#x\n", + flashid, hw->params.sf_size, FLASH_MIN_SIZE); return 0; } |