aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2009-04-01 14:11:25 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-04-03 10:23:12 -0400
commited6f7744f90a0efc6874f2ab93e4e593741079c9 (patch)
treec542fd8587927f94ac0b0cf8f7579a06b2121444 /drivers
parent9fa1926afbff77da484293bc2b0bfdb6bb2399d3 (diff)
[SCSI] cxgb3i: re-read ddp settings information after chip reset
Orignally from Karen Xie, but merge conflicts/errors fixed up by Mike Christie. Signed-off-by: Karen Xie <kxie@chelsio.com> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i.h2
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_iscsi.c114
2 files changed, 70 insertions, 46 deletions
diff --git a/drivers/scsi/cxgb3i/cxgb3i.h b/drivers/scsi/cxgb3i/cxgb3i.h
index 0942227aa7ba..d362860e7504 100644
--- a/drivers/scsi/cxgb3i/cxgb3i.h
+++ b/drivers/scsi/cxgb3i/cxgb3i.h
@@ -141,7 +141,7 @@ int cxgb3i_iscsi_init(void);
141void cxgb3i_iscsi_cleanup(void); 141void cxgb3i_iscsi_cleanup(void);
142 142
143struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *); 143struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *);
144struct cxgb3i_adapter *cxgb3i_adapter_open(struct t3cdev *); 144void cxgb3i_adapter_open(struct t3cdev *);
145void cxgb3i_adapter_close(struct t3cdev *); 145void cxgb3i_adapter_close(struct t3cdev *);
146 146
147struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *); 147struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *);
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
index ff6bfd66733f..fff8e4327644 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
@@ -71,37 +71,34 @@ struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *tdev)
71 return NULL; 71 return NULL;
72} 72}
73 73
74/** 74static inline int adapter_update(struct cxgb3i_adapter *snic)
75 * cxgb3i_adapter_open - init a s3 adapter structure and any h/w settings
76 * @t3dev: t3cdev adapter
77 * return the resulting cxgb3i_adapter struct
78 */
79struct cxgb3i_adapter *cxgb3i_adapter_open(struct t3cdev *t3dev)
80{ 75{
81 struct cxgb3i_adapter *snic; 76 cxgb3i_log_info("snic 0x%p, t3dev 0x%p, updating.\n",
82 struct adapter *adapter = tdev2adap(t3dev); 77 snic, snic->tdev);
83 int i; 78 return cxgb3i_adapter_ddp_info(snic->tdev, &snic->tag_format,
79 &snic->tx_max_size,
80 &snic->rx_max_size);
81}
84 82
85 snic = kzalloc(sizeof(*snic), GFP_KERNEL); 83static int adapter_add(struct cxgb3i_adapter *snic)
86 if (!snic) { 84{
87 cxgb3i_api_debug("cxgb3 %s, OOM.\n", t3dev->name); 85 struct t3cdev *t3dev = snic->tdev;
88 return NULL; 86 struct adapter *adapter = tdev2adap(t3dev);
89 } 87 int i, err;
90 spin_lock_init(&snic->lock);
91 88
92 snic->tdev = t3dev;
93 snic->pdev = adapter->pdev; 89 snic->pdev = adapter->pdev;
94 snic->tag_format.sw_bits = sw_tag_idx_bits + sw_tag_age_bits; 90 snic->tag_format.sw_bits = sw_tag_idx_bits + sw_tag_age_bits;
95 91
96 if (cxgb3i_adapter_ddp_init(t3dev, &snic->tag_format, 92 err = cxgb3i_adapter_ddp_info(t3dev, &snic->tag_format,
97 &snic->tx_max_size, 93 &snic->tx_max_size,
98 &snic->rx_max_size) < 0) 94 &snic->rx_max_size);
99 goto free_snic; 95 if (err < 0)
96 return err;
100 97
101 for_each_port(adapter, i) { 98 for_each_port(adapter, i) {
102 snic->hba[i] = cxgb3i_hba_host_add(snic, adapter->port[i]); 99 snic->hba[i] = cxgb3i_hba_host_add(snic, adapter->port[i]);
103 if (!snic->hba[i]) 100 if (!snic->hba[i])
104 goto ulp_cleanup; 101 return -EINVAL;
105 } 102 }
106 snic->hba_cnt = adapter->params.nports; 103 snic->hba_cnt = adapter->params.nports;
107 104
@@ -110,13 +107,40 @@ struct cxgb3i_adapter *cxgb3i_adapter_open(struct t3cdev *t3dev)
110 list_add_tail(&snic->list_head, &cxgb3i_snic_list); 107 list_add_tail(&snic->list_head, &cxgb3i_snic_list);
111 write_unlock(&cxgb3i_snic_rwlock); 108 write_unlock(&cxgb3i_snic_rwlock);
112 109
113 return snic; 110 cxgb3i_log_info("t3dev 0x%p open, snic 0x%p, %u scsi hosts added.\n",
111 t3dev, snic, snic->hba_cnt);
112 return 0;
113}
114 114
115ulp_cleanup: 115/**
116 cxgb3i_adapter_ddp_cleanup(t3dev); 116 * cxgb3i_adapter_open - init a s3 adapter structure and any h/w settings
117free_snic: 117 * @t3dev: t3cdev adapter
118 kfree(snic); 118 */
119 return NULL; 119void cxgb3i_adapter_open(struct t3cdev *t3dev)
120{
121 struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(t3dev);
122 int err;
123
124 if (snic)
125 err = adapter_update(snic);
126 else {
127 snic = kzalloc(sizeof(*snic), GFP_KERNEL);
128 if (snic) {
129 spin_lock_init(&snic->lock);
130 snic->tdev = t3dev;
131 err = adapter_add(snic);
132 } else
133 err = -ENOMEM;
134 }
135
136 if (err < 0) {
137 cxgb3i_log_info("snic 0x%p, f 0x%x, t3dev 0x%p open, err %d.\n",
138 snic, snic ? snic->flags : 0, t3dev, err);
139 if (snic) {
140 snic->flags &= ~CXGB3I_ADAPTER_FLAG_RESET;
141 cxgb3i_adapter_close(t3dev);
142 }
143 }
120} 144}
121 145
122/** 146/**
@@ -125,31 +149,29 @@ free_snic:
125 */ 149 */
126void cxgb3i_adapter_close(struct t3cdev *t3dev) 150void cxgb3i_adapter_close(struct t3cdev *t3dev)
127{ 151{
152 struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(t3dev);
128 int i; 153 int i;
129 struct cxgb3i_adapter *snic; 154
155 if (!snic || snic->flags & CXGB3I_ADAPTER_FLAG_RESET) {
156 cxgb3i_log_info("t3dev 0x%p close, snic 0x%p, f 0x%x.\n",
157 t3dev, snic, snic ? snic->flags : 0);
158 return;
159 }
130 160
131 /* remove from the list */ 161 /* remove from the list */
132 write_lock(&cxgb3i_snic_rwlock); 162 write_lock(&cxgb3i_snic_rwlock);
133 list_for_each_entry(snic, &cxgb3i_snic_list, list_head) { 163 list_del(&snic->list_head);
134 if (snic->tdev == t3dev) {
135 list_del(&snic->list_head);
136 break;
137 }
138 }
139 write_unlock(&cxgb3i_snic_rwlock); 164 write_unlock(&cxgb3i_snic_rwlock);
140 165
141 if (snic) { 166 for (i = 0; i < snic->hba_cnt; i++) {
142 for (i = 0; i < snic->hba_cnt; i++) { 167 if (snic->hba[i]) {
143 if (snic->hba[i]) { 168 cxgb3i_hba_host_remove(snic->hba[i]);
144 cxgb3i_hba_host_remove(snic->hba[i]); 169 snic->hba[i] = NULL;
145 snic->hba[i] = NULL;
146 }
147 } 170 }
148
149 /* release ddp resources */
150 cxgb3i_adapter_ddp_cleanup(snic->tdev);
151 kfree(snic);
152 } 171 }
172 cxgb3i_log_info("t3dev 0x%p close, snic 0x%p, %u scsi hosts removed.\n",
173 t3dev, snic, snic->hba_cnt);
174 kfree(snic);
153} 175}
154 176
155/** 177/**
@@ -189,7 +211,8 @@ struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *snic,
189 shost = iscsi_host_alloc(&cxgb3i_host_template, 211 shost = iscsi_host_alloc(&cxgb3i_host_template,
190 sizeof(struct cxgb3i_hba), 1); 212 sizeof(struct cxgb3i_hba), 1);
191 if (!shost) { 213 if (!shost) {
192 cxgb3i_log_info("iscsi_host_alloc failed.\n"); 214 cxgb3i_log_info("snic 0x%p, ndev 0x%p, host_alloc failed.\n",
215 snic, ndev);
193 return NULL; 216 return NULL;
194 } 217 }
195 218
@@ -207,7 +230,8 @@ struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *snic,
207 pci_dev_get(snic->pdev); 230 pci_dev_get(snic->pdev);
208 err = iscsi_host_add(shost, &snic->pdev->dev); 231 err = iscsi_host_add(shost, &snic->pdev->dev);
209 if (err) { 232 if (err) {
210 cxgb3i_log_info("iscsi_host_add failed.\n"); 233 cxgb3i_log_info("snic 0x%p, ndev 0x%p, host_add failed.\n",
234 snic, ndev);
211 goto pci_dev_put; 235 goto pci_dev_put;
212 } 236 }
213 237