aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic94xx/aic94xx_seq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aic94xx/aic94xx_seq.c')
-rw-r--r--drivers/scsi/aic94xx/aic94xx_seq.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c
index 845112539d05..eae7a247bece 100644
--- a/drivers/scsi/aic94xx/aic94xx_seq.c
+++ b/drivers/scsi/aic94xx/aic94xx_seq.c
@@ -810,6 +810,8 @@ static void asd_init_lseq_mdp(struct asd_ha_struct *asd_ha, int lseq)
810 /* No delay for the first NOTIFY to be sent to the attached target. */ 810 /* No delay for the first NOTIFY to be sent to the attached target. */
811 asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_DOWN_COUNT(lseq), 811 asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_DOWN_COUNT(lseq),
812 ASD_NOTIFY_DOWN_COUNT); 812 ASD_NOTIFY_DOWN_COUNT);
813 asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_INITIAL_COUNT(lseq),
814 ASD_NOTIFY_DOWN_COUNT);
813 815
814 /* LSEQ Mode dependent, mode 0 and 1, page 1 setup. */ 816 /* LSEQ Mode dependent, mode 0 and 1, page 1 setup. */
815 for (i = 0; i < 2; i++) { 817 for (i = 0; i < 2; i++) {
@@ -907,6 +909,16 @@ static void asd_init_scb_sites(struct asd_ha_struct *asd_ha)
907 for (i = 0; i < ASD_SCB_SIZE; i += 4) 909 for (i = 0; i < ASD_SCB_SIZE; i += 4)
908 asd_scbsite_write_dword(asd_ha, site_no, i, 0); 910 asd_scbsite_write_dword(asd_ha, site_no, i, 0);
909 911
912 /* Initialize SCB Site Opcode field to invalid. */
913 asd_scbsite_write_byte(asd_ha, site_no,
914 offsetof(struct scb_header, opcode),
915 0xFF);
916
917 /* Initialize SCB Site Flags field to mean a response
918 * frame has been received. This means inadvertent
919 * frames received to be dropped. */
920 asd_scbsite_write_byte(asd_ha, site_no, 0x49, 0x01);
921
910 /* Workaround needed by SEQ to fix a SATA issue is to exclude 922 /* Workaround needed by SEQ to fix a SATA issue is to exclude
911 * certain SCB sites from the free list. */ 923 * certain SCB sites from the free list. */
912 if (!SCB_SITE_VALID(site_no)) 924 if (!SCB_SITE_VALID(site_no))
@@ -922,16 +934,6 @@ static void asd_init_scb_sites(struct asd_ha_struct *asd_ha)
922 /* Q_NEXT field of the last SCB is invalidated. */ 934 /* Q_NEXT field of the last SCB is invalidated. */
923 asd_scbsite_write_word(asd_ha, site_no, 0, first_scb_site_no); 935 asd_scbsite_write_word(asd_ha, site_no, 0, first_scb_site_no);
924 936
925 /* Initialize SCB Site Opcode field to invalid. */
926 asd_scbsite_write_byte(asd_ha, site_no,
927 offsetof(struct scb_header, opcode),
928 0xFF);
929
930 /* Initialize SCB Site Flags field to mean a response
931 * frame has been received. This means inadvertent
932 * frames received to be dropped. */
933 asd_scbsite_write_byte(asd_ha, site_no, 0x49, 0x01);
934
935 first_scb_site_no = site_no; 937 first_scb_site_no = site_no;
936 max_scbs++; 938 max_scbs++;
937 } 939 }
@@ -1173,6 +1175,16 @@ static void asd_init_ddb_0(struct asd_ha_struct *asd_ha)
1173 set_bit(0, asd_ha->hw_prof.ddb_bitmap); 1175 set_bit(0, asd_ha->hw_prof.ddb_bitmap);
1174} 1176}
1175 1177
1178static void asd_seq_init_ddb_sites(struct asd_ha_struct *asd_ha)
1179{
1180 unsigned int i;
1181 unsigned int ddb_site;
1182
1183 for (ddb_site = 0 ; ddb_site < ASD_MAX_DDBS; ddb_site++)
1184 for (i = 0; i < sizeof(struct asd_ddb_ssp_smp_target_port); i+= 4)
1185 asd_ddbsite_write_dword(asd_ha, ddb_site, i, 0);
1186}
1187
1176/** 1188/**
1177 * asd_seq_setup_seqs -- setup and initialize central and link sequencers 1189 * asd_seq_setup_seqs -- setup and initialize central and link sequencers
1178 * @asd_ha: pointer to host adapter structure 1190 * @asd_ha: pointer to host adapter structure
@@ -1182,6 +1194,9 @@ static void asd_seq_setup_seqs(struct asd_ha_struct *asd_ha)
1182 int lseq; 1194 int lseq;
1183 u8 lseq_mask; 1195 u8 lseq_mask;
1184 1196
1197 /* Initialize DDB sites */
1198 asd_seq_init_ddb_sites(asd_ha);
1199
1185 /* Initialize SCB sites. Done first to compute some values which 1200 /* Initialize SCB sites. Done first to compute some values which
1186 * the rest of the init code depends on. */ 1201 * the rest of the init code depends on. */
1187 asd_init_scb_sites(asd_ha); 1202 asd_init_scb_sites(asd_ha);
@@ -1232,6 +1247,13 @@ static int asd_seq_start_lseq(struct asd_ha_struct *asd_ha, int lseq)
1232 return asd_seq_unpause_lseq(asd_ha, lseq); 1247 return asd_seq_unpause_lseq(asd_ha, lseq);
1233} 1248}
1234 1249
1250int asd_release_firmware(void)
1251{
1252 if (sequencer_fw)
1253 release_firmware(sequencer_fw);
1254 return 0;
1255}
1256
1235static int asd_request_firmware(struct asd_ha_struct *asd_ha) 1257static int asd_request_firmware(struct asd_ha_struct *asd_ha)
1236{ 1258{
1237 int err, i; 1259 int err, i;
@@ -1375,7 +1397,9 @@ void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
1375 u8 phy_is_up; 1397 u8 phy_is_up;
1376 u8 mask; 1398 u8 mask;
1377 int i, err; 1399 int i, err;
1400 unsigned long flags;
1378 1401
1402 spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);
1379 for_each_phy(phy_mask, mask, i) 1403 for_each_phy(phy_mask, mask, i)
1380 asd_ddbsite_write_byte(asd_ha, 0, 1404 asd_ddbsite_write_byte(asd_ha, 0,
1381 offsetof(struct asd_ddb_seq_shared, 1405 offsetof(struct asd_ddb_seq_shared,
@@ -1395,6 +1419,7 @@ void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
1395 break; 1419 break;
1396 } 1420 }
1397 } 1421 }
1422 spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
1398 1423
1399 if (err) 1424 if (err)
1400 asd_printk("couldn't update DDB 0:error:%d\n", err); 1425 asd_printk("couldn't update DDB 0:error:%d\n", err);