Skip to contentSkip to conversation

esp: Do not overwrite ESP_TCHI after reset

PATCH In review Hannes Reinecke 2 participants 5 messages Nov 10, 2014 – Nov 11, 2014

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 esp: Do not overwrite ESP_TCHI after reset

After a reset ESP_TCHI should contain the unique ID of the chip. This value will be overwritten with the current tranfer count if the transfer count has previously been set.
So we should always return the chip id if ESP_TCHI has never been written to.

---
 hw/scsi/esp.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
hw/scsi/esp.c +5 -1
index 5ab44d8..2caac1c 100644
@@ -364,7 +364,6 @@ void esp_hard_reset(ESPState *s)
 {
     memset(s->rregs, 0, ESP_REGS);
     memset(s->wregs, 0, ESP_REGS);
-    s->rregs[ESP_TCHI] = s->chip_id;
     s->ti_size = 0;
     s->ti_rptr = 0;
     s->ti_wptr = 0;
@@ -422,6 +421,11 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
         esp_lower_irq(s);
 
         return old_val;
+    case ESP_TCHI:
+        /* Return the unique id if the value has never been written */
+        if (!s->wregs[ESP_TCHI]) {
+            return s->chip_id;
+        }
     default:
         break;
     }
Signature · 1 line
1.7.12.4
#1 lore raw
Quoted 6 lines · Hannes Reinecke

After a reset ESP_TCHI should contain the unique ID of the chip. This value will be overwritten with the current tranfer count if the transfer count has previously been set.
So we should always return the chip id if ESP_TCHI has never been written to.

What if ESP_TCHI was written 0? Why should it return the chip id?

Can you explain exactly what sequence of register reads/writes leads to the bug?

Paolo

Quoted 30 lines
---
 hw/scsi/esp.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
hw/scsi/esp.c +5 -1
index 5ab44d8..2caac1c 100644
@@ -364,7 +364,6 @@ void esp_hard_reset(ESPState *s)
 {
     memset(s->rregs, 0, ESP_REGS);
     memset(s->wregs, 0, ESP_REGS);
-    s->rregs[ESP_TCHI] = s->chip_id;
     s->ti_size = 0;
     s->ti_rptr = 0;
     s->ti_wptr = 0;
@@ -422,6 +421,11 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
         esp_lower_irq(s);
 
         return old_val;
+    case ESP_TCHI:
+        /* Return the unique id if the value has never been written */
+        if (!s->wregs[ESP_TCHI]) {
+            return s->chip_id;
+        }
     default:
         break;
     }
#2 lore raw
Quoted 10 lines · Paolo Bonzini
Quoted 6 lines · Hannes Reinecke

After a reset ESP_TCHI should contain the unique ID of the chip. This value will be overwritten with the current tranfer count if the transfer count has previously been set.
So we should always return the chip id if ESP_TCHI has never been written to.

What if ESP_TCHI was written 0? Why should it return the chip id?

It's a complex thing. The documentation says 'ESP_TCHI returns the chip id until been written to'.
And ESP_TCHI is strictly speaking only valid if the 'Features enabled' bit is set in ESP_CFG2. (Not that the driver checks this). To handle it correctly we would need to add a flag whenever ESP_TCHI is written to, but I thought it'd be slightly too much.
Plus we're reloading the ESP_TCHI register anyway whenever a transfer is started.

Quoted 3 lines

Can you explain exactly what sequence of register reads/writes leads to the bug?

CMD RST
DMA CMD NOP
-> ESP_TCHI should contain chip_id, but doesn't.

Cheers,

Hannes

Signature · 4 lines
Dr. Hannes Reinecke		      zSeries & Storage
[email protected]			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
#3 lore raw
Quoted 9 lines · Hannes Reinecke
Quoted 8 lines · Paolo Bonzini
Quoted 6 lines · Hannes Reinecke

After a reset ESP_TCHI should contain the unique ID of the chip. This value will be overwritten with the current tranfer count if the transfer count has previously been set.
So we should always return the chip id if ESP_TCHI has never been written to.

Quoted 8 lines
Quoted 2 lines

What if ESP_TCHI was written 0? Why should it return the chip id?

It's a complex thing. The documentation says 'ESP_TCHI returns the chip id until been written to'.
And ESP_TCHI is strictly speaking only valid if the 'Features enabled' bit is set in ESP_CFG2. (Not that the driver checks this). To handle it correctly we would need to add a flag whenever ESP_TCHI is written to, but I thought it'd be slightly too much.

I'm worried that the chip_id will reappear if you write a low (<65536) value to ESP_TCLOW/MED/HI.

Adding the flag is just a couple lines more than this patch, let's do it right.

Paolo

#4 lore raw
Quoted 21 lines · Paolo Bonzini
Quoted 9 lines · Hannes Reinecke
Quoted 8 lines · Paolo Bonzini
Quoted 6 lines · Hannes Reinecke

After a reset ESP_TCHI should contain the unique ID of the chip. This value will be overwritten with the current tranfer count if the transfer count has previously been set.
So we should always return the chip id if ESP_TCHI has never been written to.

Quoted 8 lines
Quoted 2 lines

What if ESP_TCHI was written 0? Why should it return the chip id?

It's a complex thing. The documentation says 'ESP_TCHI returns the chip id until been written to'.
And ESP_TCHI is strictly speaking only valid if the 'Features enabled' bit is set in ESP_CFG2. (Not that the driver checks this). To handle it correctly we would need to add a flag whenever ESP_TCHI is written to, but I thought it'd be slightly too much.

Quoted 6 lines

I'm worried that the chip_id will reappear if you write a low (<65536) value to ESP_TCLOW/MED/HI.

Adding the flag is just a couple lines more than this patch, let's do it right.

Right.

Will be sending an updated patch.

Cheers,

Hannes

Signature · 4 lines
Dr. Hannes Reinecke		      zSeries & Storage
[email protected]			      +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 21284 (AG Nürnberg)